Merge pull request #974 from embassy-rs/afit
Switch to async-fn-in-trait
This commit is contained in:
		@@ -20,7 +20,7 @@ nightly = ["embedded-hal-async", "embedded-storage-async"]
 | 
			
		||||
embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
 | 
			
		||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3", optional = true }
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true }
 | 
			
		||||
embedded-storage = "0.3.0"
 | 
			
		||||
embedded-storage-async = { version = "0.3.0", optional = true }
 | 
			
		||||
nb = "1.0.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -38,32 +38,31 @@ where
 | 
			
		||||
    E: embedded_hal_1::i2c::Error + 'static,
 | 
			
		||||
    T: blocking::i2c::WriteRead<Error = E> + blocking::i2c::Read<Error = E> + blocking::i2c::Write<Error = E>,
 | 
			
		||||
{
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
    type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async move { self.wrapped.read(address, buffer) }
 | 
			
		||||
    async fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
        self.wrapped.read(address, buffer)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async move { self.wrapped.write(address, bytes) }
 | 
			
		||||
    async fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
        self.wrapped.write(address, bytes)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn write_read<'a>(&'a mut self, address: u8, bytes: &'a [u8], buffer: &'a mut [u8]) -> Self::WriteReadFuture<'a> {
 | 
			
		||||
        async move { self.wrapped.write_read(address, bytes, buffer) }
 | 
			
		||||
    async fn write_read<'a>(
 | 
			
		||||
        &'a mut self,
 | 
			
		||||
        address: u8,
 | 
			
		||||
        bytes: &'a [u8],
 | 
			
		||||
        buffer: &'a mut [u8],
 | 
			
		||||
    ) -> Result<(), Self::Error> {
 | 
			
		||||
        self.wrapped.write_read(address, bytes, buffer)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
 | 
			
		||||
 | 
			
		||||
    fn transaction<'a, 'b>(
 | 
			
		||||
    async fn transaction<'a, 'b>(
 | 
			
		||||
        &'a mut self,
 | 
			
		||||
        address: u8,
 | 
			
		||||
        operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
 | 
			
		||||
    ) -> Self::TransactionFuture<'a, 'b> {
 | 
			
		||||
    ) -> Result<(), Self::Error> {
 | 
			
		||||
        let _ = address;
 | 
			
		||||
        let _ = operations;
 | 
			
		||||
        async move { todo!() }
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -84,23 +83,17 @@ where
 | 
			
		||||
    E: embedded_hal_1::spi::Error + 'static,
 | 
			
		||||
    T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
 | 
			
		||||
{
 | 
			
		||||
    type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            // Ensure we write the expected bytes
 | 
			
		||||
            for i in 0..core::cmp::min(read.len(), write.len()) {
 | 
			
		||||
                read[i] = write[i].clone();
 | 
			
		||||
            }
 | 
			
		||||
            self.wrapped.transfer(read)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
    async fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
        // Ensure we write the expected bytes
 | 
			
		||||
        for i in 0..core::cmp::min(read.len(), write.len()) {
 | 
			
		||||
            read[i] = write[i].clone();
 | 
			
		||||
        }
 | 
			
		||||
        self.wrapped.transfer(read)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> {
 | 
			
		||||
        async move { todo!() }
 | 
			
		||||
    async fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -109,10 +102,8 @@ where
 | 
			
		||||
    E: embedded_hal_1::spi::Error + 'static,
 | 
			
		||||
    T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
 | 
			
		||||
{
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        async move { Ok(()) }
 | 
			
		||||
    async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -121,13 +112,9 @@ where
 | 
			
		||||
    E: embedded_hal_1::spi::Error + 'static,
 | 
			
		||||
    T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
 | 
			
		||||
{
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            self.wrapped.write(data)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    async fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> {
 | 
			
		||||
        self.wrapped.write(data)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -136,13 +123,9 @@ where
 | 
			
		||||
    E: embedded_hal_1::spi::Error + 'static,
 | 
			
		||||
    T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
 | 
			
		||||
{
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            self.wrapped.transfer(data)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    async fn read(&mut self, data: &mut [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
        self.wrapped.transfer(data)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -192,7 +175,7 @@ where
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where T: 'a;
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
    fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        async move { self.wrapped.bflush() }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
#![cfg_attr(not(feature = "std"), no_std)]
 | 
			
		||||
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
 | 
			
		||||
#![cfg_attr(
 | 
			
		||||
    feature = "nightly",
 | 
			
		||||
    feature(type_alias_impl_trait, async_fn_in_trait, impl_trait_projections)
 | 
			
		||||
)]
 | 
			
		||||
#![cfg_attr(feature = "nightly", allow(incomplete_features))]
 | 
			
		||||
#![warn(missing_docs)]
 | 
			
		||||
 | 
			
		||||
//! Utilities to use `embedded-hal` traits with Embassy.
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@
 | 
			
		||||
//! let i2c_dev2 = I2cDevice::new(i2c_bus);
 | 
			
		||||
//! let mpu = Mpu6050::new(i2c_dev2);
 | 
			
		||||
//! ```
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
 | 
			
		||||
use embassy_sync::blocking_mutex::raw::RawMutex;
 | 
			
		||||
use embassy_sync::mutex::Mutex;
 | 
			
		||||
@@ -55,53 +54,39 @@ where
 | 
			
		||||
    M: RawMutex + 'static,
 | 
			
		||||
    BUS: i2c::I2c + 'static,
 | 
			
		||||
{
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    async fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    async fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write_read<'a>(
 | 
			
		||||
    async fn write_read<'a>(
 | 
			
		||||
        &'a mut self,
 | 
			
		||||
        address: u8,
 | 
			
		||||
        wr_buffer: &'a [u8],
 | 
			
		||||
        rd_buffer: &'a mut [u8],
 | 
			
		||||
    ) -> Self::WriteReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            bus.write_read(address, wr_buffer, rd_buffer)
 | 
			
		||||
                .await
 | 
			
		||||
                .map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    ) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        bus.write_read(address, wr_buffer, rd_buffer)
 | 
			
		||||
            .await
 | 
			
		||||
            .map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
 | 
			
		||||
 | 
			
		||||
    fn transaction<'a, 'b>(
 | 
			
		||||
    async fn transaction<'a, 'b>(
 | 
			
		||||
        &'a mut self,
 | 
			
		||||
        address: u8,
 | 
			
		||||
        operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
 | 
			
		||||
    ) -> Self::TransactionFuture<'a, 'b> {
 | 
			
		||||
    ) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let _ = address;
 | 
			
		||||
        let _ = operations;
 | 
			
		||||
        async move { todo!() }
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -136,55 +121,41 @@ where
 | 
			
		||||
    M: RawMutex + 'static,
 | 
			
		||||
    BUS: i2c::I2c + SetConfig + 'static,
 | 
			
		||||
{
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            bus.set_config(&self.config);
 | 
			
		||||
            bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    async fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        bus.set_config(&self.config);
 | 
			
		||||
        bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            bus.set_config(&self.config);
 | 
			
		||||
            bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    async fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        bus.set_config(&self.config);
 | 
			
		||||
        bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write_read<'a>(
 | 
			
		||||
    async fn write_read<'a>(
 | 
			
		||||
        &'a mut self,
 | 
			
		||||
        address: u8,
 | 
			
		||||
        wr_buffer: &'a [u8],
 | 
			
		||||
        rd_buffer: &'a mut [u8],
 | 
			
		||||
    ) -> Self::WriteReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            bus.set_config(&self.config);
 | 
			
		||||
            bus.write_read(address, wr_buffer, rd_buffer)
 | 
			
		||||
                .await
 | 
			
		||||
                .map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    ) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        bus.set_config(&self.config);
 | 
			
		||||
        bus.write_read(address, wr_buffer, rd_buffer)
 | 
			
		||||
            .await
 | 
			
		||||
            .map_err(I2cDeviceError::I2c)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
 | 
			
		||||
 | 
			
		||||
    fn transaction<'a, 'b>(
 | 
			
		||||
    async fn transaction<'a, 'b>(
 | 
			
		||||
        &'a mut self,
 | 
			
		||||
        address: u8,
 | 
			
		||||
        operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
 | 
			
		||||
    ) -> Self::TransactionFuture<'a, 'b> {
 | 
			
		||||
    ) -> Result<(), I2cDeviceError<BUS::Error>> {
 | 
			
		||||
        let _ = address;
 | 
			
		||||
        let _ = operations;
 | 
			
		||||
        async move { todo!() }
 | 
			
		||||
        todo!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -65,33 +65,25 @@ where
 | 
			
		||||
{
 | 
			
		||||
    type Bus = BUS;
 | 
			
		||||
 | 
			
		||||
    type TransactionFuture<'a, R, F, Fut> = impl Future<Output = Result<R, Self::Error>> + 'a
 | 
			
		||||
    async fn transaction<R, F, Fut>(&mut self, f: F) -> Result<R, Self::Error>
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a, R: 'a, F: FnOnce(*mut Self::Bus) -> Fut + 'a,
 | 
			
		||||
        Fut: Future<Output =  Result<R, <Self::Bus as ErrorType>::Error>> + 'a;
 | 
			
		||||
 | 
			
		||||
    fn transaction<'a, R, F, Fut>(&'a mut self, f: F) -> Self::TransactionFuture<'a, R, F, Fut>
 | 
			
		||||
    where
 | 
			
		||||
        R: 'a,
 | 
			
		||||
        F: FnOnce(*mut Self::Bus) -> Fut + 'a,
 | 
			
		||||
        Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>> + 'a,
 | 
			
		||||
        F: FnOnce(*mut Self::Bus) -> Fut,
 | 
			
		||||
        Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>>,
 | 
			
		||||
    {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            self.cs.set_low().map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        self.cs.set_low().map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
 | 
			
		||||
            let f_res = f(&mut *bus).await;
 | 
			
		||||
        let f_res = f(&mut *bus).await;
 | 
			
		||||
 | 
			
		||||
            // On failure, it's important to still flush and deassert CS.
 | 
			
		||||
            let flush_res = bus.flush().await;
 | 
			
		||||
            let cs_res = self.cs.set_high();
 | 
			
		||||
        // On failure, it's important to still flush and deassert CS.
 | 
			
		||||
        let flush_res = bus.flush().await;
 | 
			
		||||
        let cs_res = self.cs.set_high();
 | 
			
		||||
 | 
			
		||||
            let f_res = f_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
            flush_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
            cs_res.map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
        let f_res = f_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
        flush_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
        cs_res.map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
 | 
			
		||||
            Ok(f_res)
 | 
			
		||||
        }
 | 
			
		||||
        Ok(f_res)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -130,33 +122,25 @@ where
 | 
			
		||||
{
 | 
			
		||||
    type Bus = BUS;
 | 
			
		||||
 | 
			
		||||
    type TransactionFuture<'a, R, F, Fut> = impl Future<Output = Result<R, Self::Error>> + 'a
 | 
			
		||||
    async fn transaction<R, F, Fut>(&mut self, f: F) -> Result<R, Self::Error>
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a, R: 'a, F: FnOnce(*mut Self::Bus) -> Fut + 'a,
 | 
			
		||||
        Fut: Future<Output =  Result<R, <Self::Bus as ErrorType>::Error>> + 'a;
 | 
			
		||||
 | 
			
		||||
    fn transaction<'a, R, F, Fut>(&'a mut self, f: F) -> Self::TransactionFuture<'a, R, F, Fut>
 | 
			
		||||
    where
 | 
			
		||||
        R: 'a,
 | 
			
		||||
        F: FnOnce(*mut Self::Bus) -> Fut + 'a,
 | 
			
		||||
        Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>> + 'a,
 | 
			
		||||
        F: FnOnce(*mut Self::Bus) -> Fut,
 | 
			
		||||
        Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>>,
 | 
			
		||||
    {
 | 
			
		||||
        async move {
 | 
			
		||||
            let mut bus = self.bus.lock().await;
 | 
			
		||||
            bus.set_config(&self.config);
 | 
			
		||||
            self.cs.set_low().map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
        let mut bus = self.bus.lock().await;
 | 
			
		||||
        bus.set_config(&self.config);
 | 
			
		||||
        self.cs.set_low().map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
 | 
			
		||||
            let f_res = f(&mut *bus).await;
 | 
			
		||||
        let f_res = f(&mut *bus).await;
 | 
			
		||||
 | 
			
		||||
            // On failure, it's important to still flush and deassert CS.
 | 
			
		||||
            let flush_res = bus.flush().await;
 | 
			
		||||
            let cs_res = self.cs.set_high();
 | 
			
		||||
        // On failure, it's important to still flush and deassert CS.
 | 
			
		||||
        let flush_res = bus.flush().await;
 | 
			
		||||
        let cs_res = self.cs.set_high();
 | 
			
		||||
 | 
			
		||||
            let f_res = f_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
            flush_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
            cs_res.map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
        let f_res = f_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
        flush_res.map_err(SpiDeviceError::Spi)?;
 | 
			
		||||
        cs_res.map_err(SpiDeviceError::Cs)?;
 | 
			
		||||
 | 
			
		||||
            Ok(f_res)
 | 
			
		||||
        }
 | 
			
		||||
        Ok(f_res)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ embassy-time = { version = "0.1.0", path = "../embassy-time" }
 | 
			
		||||
embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
 | 
			
		||||
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3" }
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0" }
 | 
			
		||||
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
 | 
			
		||||
embedded-hal = { version = "0.2", features = ["unproven"] }
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ log = { version = "0.4.14", optional = true }
 | 
			
		||||
 | 
			
		||||
embassy-time = { version = "0.1.0", path = "../embassy-time" }
 | 
			
		||||
embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
 | 
			
		||||
embedded-io = { version = "0.3.1", optional = true }
 | 
			
		||||
embedded-io = { version = "0.4.0", optional = true }
 | 
			
		||||
 | 
			
		||||
managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
 | 
			
		||||
heapless = { version = "0.7.5", default-features = false }
 | 
			
		||||
@@ -52,7 +52,7 @@ stable_deref_trait = { version = "1.2.0", default-features = false }
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
 | 
			
		||||
atomic-pool = "1.0"
 | 
			
		||||
atomic-polyfill = "1.0.1"
 | 
			
		||||
embedded-nal-async = { version = "0.2.0", optional = true }
 | 
			
		||||
embedded-nal-async = { git = "https://github.com/embassy-rs/embedded-nal.git", rev = "691601e550449a53ab3a7c5eaa0411aee0a64ed0", optional = true }
 | 
			
		||||
 | 
			
		||||
[dependencies.smoltcp]
 | 
			
		||||
version = "0.8.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
#![cfg_attr(not(feature = "std"), no_std)]
 | 
			
		||||
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
 | 
			
		||||
#![cfg_attr(
 | 
			
		||||
    feature = "nightly",
 | 
			
		||||
    feature(type_alias_impl_trait, async_fn_in_trait, impl_trait_projections)
 | 
			
		||||
)]
 | 
			
		||||
#![cfg_attr(feature = "nightly", allow(incomplete_features))]
 | 
			
		||||
 | 
			
		||||
// This mod MUST go first, so that the others see its macros.
 | 
			
		||||
pub(crate) mod fmt;
 | 
			
		||||
 
 | 
			
		||||
@@ -271,8 +271,6 @@ impl<'d> TcpIo<'d> {
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "nightly")]
 | 
			
		||||
mod embedded_io_impls {
 | 
			
		||||
    use core::future::Future;
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    impl embedded_io::Error for ConnectError {
 | 
			
		||||
@@ -292,30 +290,18 @@ mod embedded_io_impls {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d> embedded_io::asynch::Read for TcpSocket<'d> {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.io.read(buf)
 | 
			
		||||
        async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
            self.io.read(buf).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d> embedded_io::asynch::Write for TcpSocket<'d> {
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.io.write(buf)
 | 
			
		||||
        async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
            self.io.write(buf).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
            self.io.flush()
 | 
			
		||||
        async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.io.flush().await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -324,12 +310,8 @@ mod embedded_io_impls {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d> embedded_io::asynch::Read for TcpReader<'d> {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.io.read(buf)
 | 
			
		||||
        async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
            self.io.read(buf).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -338,27 +320,18 @@ mod embedded_io_impls {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d> embedded_io::asynch::Write for TcpWriter<'d> {
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.io.write(buf)
 | 
			
		||||
        async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
            self.io.write(buf).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
            self.io.flush()
 | 
			
		||||
        async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.io.flush().await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
pub mod client {
 | 
			
		||||
    use core::future::Future;
 | 
			
		||||
    use core::mem::MaybeUninit;
 | 
			
		||||
    use core::ptr::NonNull;
 | 
			
		||||
 | 
			
		||||
@@ -385,28 +358,29 @@ pub mod client {
 | 
			
		||||
    {
 | 
			
		||||
        type Error = Error;
 | 
			
		||||
        type Connection<'m> = TcpConnection<'m, N, TX_SZ, RX_SZ> where Self: 'm;
 | 
			
		||||
        type ConnectFuture<'m> = impl Future<Output = Result<Self::Connection<'m>, Self::Error>> + 'm
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'm;
 | 
			
		||||
 | 
			
		||||
        fn connect<'m>(&'m self, remote: embedded_nal_async::SocketAddr) -> Self::ConnectFuture<'m> {
 | 
			
		||||
            async move {
 | 
			
		||||
                let addr: crate::IpAddress = match remote.ip() {
 | 
			
		||||
                    IpAddr::V4(addr) => crate::IpAddress::Ipv4(crate::Ipv4Address::from_bytes(&addr.octets())),
 | 
			
		||||
                    #[cfg(feature = "proto-ipv6")]
 | 
			
		||||
                    IpAddr::V6(addr) => crate::IpAddress::Ipv6(crate::Ipv6Address::from_bytes(&addr.octets())),
 | 
			
		||||
                    #[cfg(not(feature = "proto-ipv6"))]
 | 
			
		||||
                    IpAddr::V6(_) => panic!("ipv6 support not enabled"),
 | 
			
		||||
                };
 | 
			
		||||
                let remote_endpoint = (addr, remote.port());
 | 
			
		||||
                let mut socket = TcpConnection::new(&self.stack, self.state)?;
 | 
			
		||||
                socket
 | 
			
		||||
                    .socket
 | 
			
		||||
                    .connect(remote_endpoint)
 | 
			
		||||
                    .await
 | 
			
		||||
                    .map_err(|_| Error::ConnectionReset)?;
 | 
			
		||||
                Ok(socket)
 | 
			
		||||
            }
 | 
			
		||||
        async fn connect<'a>(
 | 
			
		||||
            &'a self,
 | 
			
		||||
            remote: embedded_nal_async::SocketAddr,
 | 
			
		||||
        ) -> Result<Self::Connection<'a>, Self::Error>
 | 
			
		||||
        where
 | 
			
		||||
            Self: 'a,
 | 
			
		||||
        {
 | 
			
		||||
            let addr: crate::IpAddress = match remote.ip() {
 | 
			
		||||
                IpAddr::V4(addr) => crate::IpAddress::Ipv4(crate::Ipv4Address::from_bytes(&addr.octets())),
 | 
			
		||||
                #[cfg(feature = "proto-ipv6")]
 | 
			
		||||
                IpAddr::V6(addr) => crate::IpAddress::Ipv6(crate::Ipv6Address::from_bytes(&addr.octets())),
 | 
			
		||||
                #[cfg(not(feature = "proto-ipv6"))]
 | 
			
		||||
                IpAddr::V6(_) => panic!("ipv6 support not enabled"),
 | 
			
		||||
            };
 | 
			
		||||
            let remote_endpoint = (addr, remote.port());
 | 
			
		||||
            let mut socket = TcpConnection::new(&self.stack, self.state)?;
 | 
			
		||||
            socket
 | 
			
		||||
                .socket
 | 
			
		||||
                .connect(remote_endpoint)
 | 
			
		||||
                .await
 | 
			
		||||
                .map_err(|_| Error::ConnectionReset)?;
 | 
			
		||||
            Ok(socket)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -445,32 +419,20 @@ pub mod client {
 | 
			
		||||
    impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_io::asynch::Read
 | 
			
		||||
        for TcpConnection<'d, N, TX_SZ, RX_SZ>
 | 
			
		||||
    {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.socket.read(buf)
 | 
			
		||||
        async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
            self.socket.read(buf).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, const N: usize, const TX_SZ: usize, const RX_SZ: usize> embedded_io::asynch::Write
 | 
			
		||||
        for TcpConnection<'d, N, TX_SZ, RX_SZ>
 | 
			
		||||
    {
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.socket.write(buf)
 | 
			
		||||
        async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
            self.socket.write(buf).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
            self.socket.flush()
 | 
			
		||||
        async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.socket.flush().await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -75,8 +75,8 @@ embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optiona
 | 
			
		||||
 | 
			
		||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9", optional = true}
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3", optional = true}
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async"], optional = true }
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true}
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
 | 
			
		||||
 | 
			
		||||
defmt = { version = "0.3", optional = true }
 | 
			
		||||
log = { version = "0.4.14", optional = true }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
use core::cell::RefCell;
 | 
			
		||||
use core::cmp::min;
 | 
			
		||||
use core::future::{poll_fn, Future};
 | 
			
		||||
use core::future::poll_fn;
 | 
			
		||||
use core::sync::atomic::{compiler_fence, Ordering};
 | 
			
		||||
use core::task::Poll;
 | 
			
		||||
 | 
			
		||||
@@ -341,32 +341,20 @@ impl<'u, 'd, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUar
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for BufferedUarte<'d, U, T> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        self.inner_read(buf)
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner_read(buf).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for BufferedUarteRx<'u, 'd, U, T> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        self.inner.inner_read(buf)
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner.inner_read(buf).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRead for BufferedUarte<'d, U, T> {
 | 
			
		||||
    type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> {
 | 
			
		||||
        self.inner_fill_buf()
 | 
			
		||||
    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
 | 
			
		||||
        self.inner_fill_buf().await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn consume(&mut self, amt: usize) {
 | 
			
		||||
@@ -375,12 +363,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRead for Bu
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRead for BufferedUarteRx<'u, 'd, U, T> {
 | 
			
		||||
    type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> {
 | 
			
		||||
        self.inner.inner_fill_buf()
 | 
			
		||||
    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
 | 
			
		||||
        self.inner.inner_fill_buf().await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn consume(&mut self, amt: usize) {
 | 
			
		||||
@@ -389,38 +373,22 @@ impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRea
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write for BufferedUarte<'d, U, T> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        self.inner_write(buf)
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner_write(buf).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        self.inner_flush()
 | 
			
		||||
    async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        self.inner_flush().await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write for BufferedUarteTx<'u, 'd, U, T> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        self.inner.inner_write(buf)
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner.inner_write(buf).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        self.inner.inner_flush()
 | 
			
		||||
    async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        self.inner.inner_flush().await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -473,71 +473,49 @@ mod eh1 {
 | 
			
		||||
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
mod eha {
 | 
			
		||||
    use futures::FutureExt;
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Input<'d, T> {
 | 
			
		||||
        type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
 | 
			
		||||
            self.wait_for_high().map(Ok)
 | 
			
		||||
        async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_high().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
 | 
			
		||||
            self.wait_for_low().map(Ok)
 | 
			
		||||
        async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_low().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_rising_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_rising_edge().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_falling_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_falling_edge().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_any_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_any_edge().await)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for Flex<'d, T> {
 | 
			
		||||
        type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
 | 
			
		||||
            self.wait_for_high().map(Ok)
 | 
			
		||||
        async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_high().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
 | 
			
		||||
            self.wait_for_low().map(Ok)
 | 
			
		||||
        async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_low().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_rising_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_rising_edge().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_falling_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_falling_edge().await)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_any_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(self.wait_for_any_edge().await)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,11 @@
 | 
			
		||||
//! mutable slices always reside in RAM.
 | 
			
		||||
 | 
			
		||||
#![no_std]
 | 
			
		||||
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
 | 
			
		||||
#![cfg_attr(
 | 
			
		||||
    feature = "nightly",
 | 
			
		||||
    feature(type_alias_impl_trait, async_fn_in_trait, impl_trait_projections)
 | 
			
		||||
)]
 | 
			
		||||
#![cfg_attr(feature = "nightly", allow(incomplete_features))]
 | 
			
		||||
 | 
			
		||||
#[cfg(not(any(
 | 
			
		||||
    feature = "nrf51",
 | 
			
		||||
 
 | 
			
		||||
@@ -477,45 +477,34 @@ mod eh1 {
 | 
			
		||||
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
mod eha {
 | 
			
		||||
    use core::future::Future;
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBusFlush for Spim<'d, T> {
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
            async move { Ok(()) }
 | 
			
		||||
        async fn flush(&mut self) -> Result<(), Error> {
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBusRead<u8> for Spim<'d, T> {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.read(words)
 | 
			
		||||
        async fn read(&mut self, words: &mut [u8]) -> Result<(), Error> {
 | 
			
		||||
            self.read(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBusWrite<u8> for Spim<'d, T> {
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.write(data)
 | 
			
		||||
        async fn write(&mut self, data: &[u8]) -> Result<(), Error> {
 | 
			
		||||
            self.write(data).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
 | 
			
		||||
        type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
 | 
			
		||||
            self.transfer(rx, tx)
 | 
			
		||||
        async fn transfer(&mut self, rx: &mut [u8], tx: &[u8]) -> Result<(), Error> {
 | 
			
		||||
            self.transfer(rx, tx).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transfer_in_place<'a>(&'a mut self, words: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> {
 | 
			
		||||
            self.transfer_in_place(words)
 | 
			
		||||
        async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> {
 | 
			
		||||
            self.transfer_in_place(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -841,39 +841,31 @@ mod eh1 {
 | 
			
		||||
mod eha {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.read(address, buffer)
 | 
			
		||||
        async fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Result<(), Error> {
 | 
			
		||||
            self.read(address, buffer).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.write(address, bytes)
 | 
			
		||||
        async fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Result<(), Error> {
 | 
			
		||||
            self.write(address, bytes).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write_read<'a>(
 | 
			
		||||
        async fn write_read<'a>(
 | 
			
		||||
            &'a mut self,
 | 
			
		||||
            address: u8,
 | 
			
		||||
            wr_buffer: &'a [u8],
 | 
			
		||||
            rd_buffer: &'a mut [u8],
 | 
			
		||||
        ) -> Self::WriteReadFuture<'a> {
 | 
			
		||||
            self.write_read(address, wr_buffer, rd_buffer)
 | 
			
		||||
        ) -> Result<(), Error> {
 | 
			
		||||
            self.write_read(address, wr_buffer, rd_buffer).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transaction<'a, 'b>(
 | 
			
		||||
        async fn transaction<'a, 'b>(
 | 
			
		||||
            &'a mut self,
 | 
			
		||||
            address: u8,
 | 
			
		||||
            operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
 | 
			
		||||
        ) -> Self::TransactionFuture<'a, 'b> {
 | 
			
		||||
        ) -> Result<(), Error> {
 | 
			
		||||
            let _ = address;
 | 
			
		||||
            let _ = operations;
 | 
			
		||||
            async move { todo!() }
 | 
			
		||||
            todo!()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -986,7 +986,7 @@ mod eha {
 | 
			
		||||
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            async move { Ok(()) }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1000,7 +1000,7 @@ mod eha {
 | 
			
		||||
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            async move { Ok(()) }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1012,4 +1012,26 @@ mod eha {
 | 
			
		||||
            self.read(buffer)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Read for UarteWithIdle<'d, U, T> {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.read(buffer)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Write for UarteWithIdle<'d, U, T> {
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.write(buffer)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            async move { Ok(()) }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#![macro_use]
 | 
			
		||||
 | 
			
		||||
use core::future::{poll_fn, Future};
 | 
			
		||||
use core::future::poll_fn;
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use core::mem::MaybeUninit;
 | 
			
		||||
use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU32, Ordering};
 | 
			
		||||
@@ -28,11 +28,7 @@ static READY_ENDPOINTS: AtomicU32 = AtomicU32::new(0);
 | 
			
		||||
/// here provides a hook into determining whether it is.
 | 
			
		||||
pub trait UsbSupply {
 | 
			
		||||
    fn is_usb_detected(&self) -> bool;
 | 
			
		||||
 | 
			
		||||
    type UsbPowerReadyFuture<'a>: Future<Output = Result<(), ()>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    fn wait_power_ready(&mut self) -> Self::UsbPowerReadyFuture<'_>;
 | 
			
		||||
    async fn wait_power_ready(&mut self) -> Result<(), ()>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Driver<'d, T: Instance, P: UsbSupply> {
 | 
			
		||||
@@ -102,8 +98,7 @@ impl UsbSupply for PowerUsb {
 | 
			
		||||
        regs.usbregstatus.read().vbusdetect().is_vbus_present()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type UsbPowerReadyFuture<'a> = impl Future<Output = Result<(), ()>> + 'a where Self: 'a;
 | 
			
		||||
    fn wait_power_ready(&mut self) -> Self::UsbPowerReadyFuture<'_> {
 | 
			
		||||
    async fn wait_power_ready(&mut self) -> Result<(), ()> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            POWER_WAKER.register(cx.waker());
 | 
			
		||||
            let regs = unsafe { &*pac::POWER::ptr() };
 | 
			
		||||
@@ -116,6 +111,7 @@ impl UsbSupply for PowerUsb {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -147,8 +143,7 @@ impl UsbSupply for &SignalledSupply {
 | 
			
		||||
        self.usb_detected.load(Ordering::Relaxed)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type UsbPowerReadyFuture<'a> = impl Future<Output = Result<(), ()>> + 'a where Self: 'a;
 | 
			
		||||
    fn wait_power_ready(&mut self) -> Self::UsbPowerReadyFuture<'_> {
 | 
			
		||||
    async fn wait_power_ready(&mut self) -> Result<(), ()> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            POWER_WAKER.register(cx.waker());
 | 
			
		||||
 | 
			
		||||
@@ -160,6 +155,7 @@ impl UsbSupply for &SignalledSupply {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -289,61 +285,52 @@ pub struct Bus<'d, T: Instance, P: UsbSupply> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> {
 | 
			
		||||
    type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
    type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
    type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a;
 | 
			
		||||
    type RemoteWakeupFuture<'a> = impl Future<Output = Result<(), Unsupported>> + 'a where Self: 'a;
 | 
			
		||||
    async fn enable(&mut self) {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
    fn enable(&mut self) -> Self::EnableFuture<'_> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
        errata::pre_enable();
 | 
			
		||||
 | 
			
		||||
            errata::pre_enable();
 | 
			
		||||
        regs.enable.write(|w| w.enable().enabled());
 | 
			
		||||
 | 
			
		||||
            regs.enable.write(|w| w.enable().enabled());
 | 
			
		||||
 | 
			
		||||
            // Wait until the peripheral is ready.
 | 
			
		||||
            regs.intenset.write(|w| w.usbevent().set_bit());
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                BUS_WAKER.register(cx.waker());
 | 
			
		||||
                if regs.eventcause.read().ready().is_ready() {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
            regs.eventcause.write(|w| w.ready().clear_bit_by_one());
 | 
			
		||||
 | 
			
		||||
            errata::post_enable();
 | 
			
		||||
 | 
			
		||||
            unsafe { NVIC::unmask(pac::Interrupt::USBD) };
 | 
			
		||||
 | 
			
		||||
            regs.intenset.write(|w| {
 | 
			
		||||
                w.usbreset().set_bit();
 | 
			
		||||
                w.usbevent().set_bit();
 | 
			
		||||
                w.epdata().set_bit();
 | 
			
		||||
                w
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if self.usb_supply.wait_power_ready().await.is_ok() {
 | 
			
		||||
                // Enable the USB pullup, allowing enumeration.
 | 
			
		||||
                regs.usbpullup.write(|w| w.connect().enabled());
 | 
			
		||||
                trace!("enabled");
 | 
			
		||||
        // Wait until the peripheral is ready.
 | 
			
		||||
        regs.intenset.write(|w| w.usbevent().set_bit());
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            BUS_WAKER.register(cx.waker());
 | 
			
		||||
            if regs.eventcause.read().ready().is_ready() {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                trace!("usb power not ready due to usb removal");
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
        regs.eventcause.write(|w| w.ready().clear_bit_by_one());
 | 
			
		||||
 | 
			
		||||
        errata::post_enable();
 | 
			
		||||
 | 
			
		||||
        unsafe { NVIC::unmask(pac::Interrupt::USBD) };
 | 
			
		||||
 | 
			
		||||
        regs.intenset.write(|w| {
 | 
			
		||||
            w.usbreset().set_bit();
 | 
			
		||||
            w.usbevent().set_bit();
 | 
			
		||||
            w.epdata().set_bit();
 | 
			
		||||
            w
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if self.usb_supply.wait_power_ready().await.is_ok() {
 | 
			
		||||
            // Enable the USB pullup, allowing enumeration.
 | 
			
		||||
            regs.usbpullup.write(|w| w.connect().enabled());
 | 
			
		||||
            trace!("enabled");
 | 
			
		||||
        } else {
 | 
			
		||||
            trace!("usb power not ready due to usb removal");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn disable(&mut self) -> Self::DisableFuture<'_> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            regs.enable.write(|x| x.enable().disabled());
 | 
			
		||||
        }
 | 
			
		||||
    async fn disable(&mut self) {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        regs.enable.write(|x| x.enable().disabled());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn poll<'a>(&'a mut self) -> Self::PollFuture<'a> {
 | 
			
		||||
    async fn poll(&mut self) -> Event {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            BUS_WAKER.register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
@@ -401,6 +388,7 @@ impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> {
 | 
			
		||||
 | 
			
		||||
            Poll::Pending
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
@@ -493,42 +481,40 @@ impl<'d, T: Instance, P: UsbSupply> driver::Bus for Bus<'d, T, P> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
    async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
            if regs.lowpower.read().lowpower().is_low_power() {
 | 
			
		||||
                errata::pre_wakeup();
 | 
			
		||||
        if regs.lowpower.read().lowpower().is_low_power() {
 | 
			
		||||
            errata::pre_wakeup();
 | 
			
		||||
 | 
			
		||||
                regs.lowpower.write(|w| w.lowpower().force_normal());
 | 
			
		||||
            regs.lowpower.write(|w| w.lowpower().force_normal());
 | 
			
		||||
 | 
			
		||||
                poll_fn(|cx| {
 | 
			
		||||
                    BUS_WAKER.register(cx.waker());
 | 
			
		||||
                    let regs = T::regs();
 | 
			
		||||
                    let r = regs.eventcause.read();
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                BUS_WAKER.register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                let r = regs.eventcause.read();
 | 
			
		||||
 | 
			
		||||
                    if regs.events_usbreset.read().bits() != 0 {
 | 
			
		||||
                        Poll::Ready(())
 | 
			
		||||
                    } else if r.resume().bit() {
 | 
			
		||||
                        Poll::Ready(())
 | 
			
		||||
                    } else if r.usbwuallowed().bit() {
 | 
			
		||||
                        regs.eventcause.write(|w| w.usbwuallowed().allowed());
 | 
			
		||||
                if regs.events_usbreset.read().bits() != 0 {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else if r.resume().bit() {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else if r.usbwuallowed().bit() {
 | 
			
		||||
                    regs.eventcause.write(|w| w.usbwuallowed().allowed());
 | 
			
		||||
 | 
			
		||||
                        regs.dpdmvalue.write(|w| w.state().resume());
 | 
			
		||||
                        regs.tasks_dpdmdrive.write(|w| w.tasks_dpdmdrive().set_bit());
 | 
			
		||||
                    regs.dpdmvalue.write(|w| w.state().resume());
 | 
			
		||||
                    regs.tasks_dpdmdrive.write(|w| w.tasks_dpdmdrive().set_bit());
 | 
			
		||||
 | 
			
		||||
                        Poll::Ready(())
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Poll::Pending
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .await;
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
                errata::post_wakeup();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Ok(())
 | 
			
		||||
            errata::post_wakeup();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -594,9 +580,7 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir
 | 
			
		||||
        &self.info
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> {
 | 
			
		||||
    async fn wait_enabled(&mut self) {
 | 
			
		||||
        let i = self.info.addr.index();
 | 
			
		||||
        assert!(i != 0);
 | 
			
		||||
 | 
			
		||||
@@ -608,6 +592,7 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -712,34 +697,26 @@ unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
 | 
			
		||||
        let i = self.info.addr.index();
 | 
			
		||||
        assert!(i != 0);
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let i = self.info.addr.index();
 | 
			
		||||
            assert!(i != 0);
 | 
			
		||||
        self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
 | 
			
		||||
 | 
			
		||||
            self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
 | 
			
		||||
 | 
			
		||||
            unsafe { read_dma::<T>(i, buf) }
 | 
			
		||||
        }
 | 
			
		||||
        unsafe { read_dma::<T>(i, buf) }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> {
 | 
			
		||||
        let i = self.info.addr.index();
 | 
			
		||||
        assert!(i != 0);
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let i = self.info.addr.index();
 | 
			
		||||
            assert!(i != 0);
 | 
			
		||||
        self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
 | 
			
		||||
 | 
			
		||||
            self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?;
 | 
			
		||||
        unsafe { write_dma::<T>(i, buf) }
 | 
			
		||||
 | 
			
		||||
            unsafe { write_dma::<T>(i, buf) }
 | 
			
		||||
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -749,136 +726,120 @@ pub struct ControlPipe<'d, T: Instance> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
			
		||||
    type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a;
 | 
			
		||||
    type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    type AcceptFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
    type RejectFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn max_packet_size(&self) -> usize {
 | 
			
		||||
        usize::from(self.max_packet_size)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
    async fn setup(&mut self) -> [u8; 8] {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
        // Reset shorts
 | 
			
		||||
        regs.shorts.write(|w| w);
 | 
			
		||||
 | 
			
		||||
        // Wait for SETUP packet
 | 
			
		||||
        regs.intenset.write(|w| w.ep0setup().set());
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP0_WAKER.register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            if regs.events_ep0setup.read().bits() != 0 {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
            // Reset shorts
 | 
			
		||||
            regs.shorts.write(|w| w);
 | 
			
		||||
        regs.events_ep0setup.reset();
 | 
			
		||||
 | 
			
		||||
            // Wait for SETUP packet
 | 
			
		||||
            regs.intenset.write(|w| w.ep0setup().set());
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP0_WAKER.register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if regs.events_ep0setup.read().bits() != 0 {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
        let mut buf = [0; 8];
 | 
			
		||||
        buf[0] = regs.bmrequesttype.read().bits() as u8;
 | 
			
		||||
        buf[1] = regs.brequest.read().brequest().bits();
 | 
			
		||||
        buf[2] = regs.wvaluel.read().wvaluel().bits();
 | 
			
		||||
        buf[3] = regs.wvalueh.read().wvalueh().bits();
 | 
			
		||||
        buf[4] = regs.windexl.read().windexl().bits();
 | 
			
		||||
        buf[5] = regs.windexh.read().windexh().bits();
 | 
			
		||||
        buf[6] = regs.wlengthl.read().wlengthl().bits();
 | 
			
		||||
        buf[7] = regs.wlengthh.read().wlengthh().bits();
 | 
			
		||||
 | 
			
		||||
            regs.events_ep0setup.reset();
 | 
			
		||||
 | 
			
		||||
            let mut buf = [0; 8];
 | 
			
		||||
            buf[0] = regs.bmrequesttype.read().bits() as u8;
 | 
			
		||||
            buf[1] = regs.brequest.read().brequest().bits();
 | 
			
		||||
            buf[2] = regs.wvaluel.read().wvaluel().bits();
 | 
			
		||||
            buf[3] = regs.wvalueh.read().wvalueh().bits();
 | 
			
		||||
            buf[4] = regs.windexl.read().windexl().bits();
 | 
			
		||||
            buf[5] = regs.windexh.read().windexh().bits();
 | 
			
		||||
            buf[6] = regs.wlengthl.read().wlengthl().bits();
 | 
			
		||||
            buf[7] = regs.wlengthh.read().wlengthh().bits();
 | 
			
		||||
 | 
			
		||||
            buf
 | 
			
		||||
        }
 | 
			
		||||
        buf
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn data_out<'a>(&'a mut self, buf: &'a mut [u8], _first: bool, _last: bool) -> Self::DataOutFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
    async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
        regs.events_ep0datadone.reset();
 | 
			
		||||
 | 
			
		||||
        // This starts a RX on EP0. events_ep0datadone notifies when done.
 | 
			
		||||
        regs.tasks_ep0rcvout.write(|w| w.tasks_ep0rcvout().set_bit());
 | 
			
		||||
 | 
			
		||||
        // Wait until ready
 | 
			
		||||
        regs.intenset.write(|w| {
 | 
			
		||||
            w.usbreset().set();
 | 
			
		||||
            w.ep0setup().set();
 | 
			
		||||
            w.ep0datadone().set()
 | 
			
		||||
        });
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP0_WAKER.register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            if regs.events_ep0datadone.read().bits() != 0 {
 | 
			
		||||
                Poll::Ready(Ok(()))
 | 
			
		||||
            } else if regs.events_usbreset.read().bits() != 0 {
 | 
			
		||||
                trace!("aborted control data_out: usb reset");
 | 
			
		||||
                Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
            } else if regs.events_ep0setup.read().bits() != 0 {
 | 
			
		||||
                trace!("aborted control data_out: received another SETUP");
 | 
			
		||||
                Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
            regs.events_ep0datadone.reset();
 | 
			
		||||
 | 
			
		||||
            // This starts a RX on EP0. events_ep0datadone notifies when done.
 | 
			
		||||
            regs.tasks_ep0rcvout.write(|w| w.tasks_ep0rcvout().set_bit());
 | 
			
		||||
 | 
			
		||||
            // Wait until ready
 | 
			
		||||
            regs.intenset.write(|w| {
 | 
			
		||||
                w.usbreset().set();
 | 
			
		||||
                w.ep0setup().set();
 | 
			
		||||
                w.ep0datadone().set()
 | 
			
		||||
            });
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP0_WAKER.register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if regs.events_ep0datadone.read().bits() != 0 {
 | 
			
		||||
                    Poll::Ready(Ok(()))
 | 
			
		||||
                } else if regs.events_usbreset.read().bits() != 0 {
 | 
			
		||||
                    trace!("aborted control data_out: usb reset");
 | 
			
		||||
                    Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
                } else if regs.events_ep0setup.read().bits() != 0 {
 | 
			
		||||
                    trace!("aborted control data_out: received another SETUP");
 | 
			
		||||
                    Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await?;
 | 
			
		||||
 | 
			
		||||
            unsafe { read_dma::<T>(0, buf) }
 | 
			
		||||
        }
 | 
			
		||||
        unsafe { read_dma::<T>(0, buf) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn data_in<'a>(&'a mut self, buf: &'a [u8], _first: bool, last: bool) -> Self::DataInFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
    async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        regs.events_ep0datadone.reset();
 | 
			
		||||
 | 
			
		||||
        regs.shorts.write(|w| w.ep0datadone_ep0status().bit(last));
 | 
			
		||||
 | 
			
		||||
        // This starts a TX on EP0. events_ep0datadone notifies when done.
 | 
			
		||||
        unsafe { write_dma::<T>(0, buf) }
 | 
			
		||||
 | 
			
		||||
        regs.intenset.write(|w| {
 | 
			
		||||
            w.usbreset().set();
 | 
			
		||||
            w.ep0setup().set();
 | 
			
		||||
            w.ep0datadone().set()
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            cx.waker().wake_by_ref();
 | 
			
		||||
            EP0_WAKER.register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            regs.events_ep0datadone.reset();
 | 
			
		||||
 | 
			
		||||
            regs.shorts.write(|w| w.ep0datadone_ep0status().bit(last));
 | 
			
		||||
 | 
			
		||||
            // This starts a TX on EP0. events_ep0datadone notifies when done.
 | 
			
		||||
            unsafe { write_dma::<T>(0, buf) }
 | 
			
		||||
 | 
			
		||||
            regs.intenset.write(|w| {
 | 
			
		||||
                w.usbreset().set();
 | 
			
		||||
                w.ep0setup().set();
 | 
			
		||||
                w.ep0datadone().set()
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                cx.waker().wake_by_ref();
 | 
			
		||||
                EP0_WAKER.register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if regs.events_ep0datadone.read().bits() != 0 {
 | 
			
		||||
                    Poll::Ready(Ok(()))
 | 
			
		||||
                } else if regs.events_usbreset.read().bits() != 0 {
 | 
			
		||||
                    trace!("aborted control data_in: usb reset");
 | 
			
		||||
                    Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
                } else if regs.events_ep0setup.read().bits() != 0 {
 | 
			
		||||
                    trace!("aborted control data_in: received another SETUP");
 | 
			
		||||
                    Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await
 | 
			
		||||
        }
 | 
			
		||||
            if regs.events_ep0datadone.read().bits() != 0 {
 | 
			
		||||
                Poll::Ready(Ok(()))
 | 
			
		||||
            } else if regs.events_usbreset.read().bits() != 0 {
 | 
			
		||||
                trace!("aborted control data_in: usb reset");
 | 
			
		||||
                Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
            } else if regs.events_ep0setup.read().bits() != 0 {
 | 
			
		||||
                trace!("aborted control data_in: received another SETUP");
 | 
			
		||||
                Poll::Ready(Err(EndpointError::Disabled))
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            regs.tasks_ep0status.write(|w| w.tasks_ep0status().bit(true));
 | 
			
		||||
        }
 | 
			
		||||
    async fn accept(&mut self) {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        regs.tasks_ep0status.write(|w| w.tasks_ep0status().bit(true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(true));
 | 
			
		||||
        }
 | 
			
		||||
    async fn reject(&mut self) {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(true));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ cortex-m = "0.7.6"
 | 
			
		||||
critical-section = "1.1"
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
 | 
			
		||||
chrono = { version = "0.4", default-features = false, optional = true }
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async"], optional = true }
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
 | 
			
		||||
embedded-storage = { version = "0.3" }
 | 
			
		||||
 | 
			
		||||
rp2040-pac2 = { git = "https://github.com/embassy-rs/rp2040-pac2", rev="017e3c9007b2d3b6965f0d85b5bf8ce3fa6d7364", features = ["rt"] }
 | 
			
		||||
@@ -61,5 +61,5 @@ rp2040-pac2 = { git = "https://github.com/embassy-rs/rp2040-pac2", rev="017e3c90
 | 
			
		||||
 | 
			
		||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9", optional = true}
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3", optional = true}
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true}
 | 
			
		||||
embedded-hal-nb = { version = "=1.0.0-alpha.1", optional = true}
 | 
			
		||||
 
 | 
			
		||||
@@ -870,9 +870,6 @@ mod eh02 {
 | 
			
		||||
mod eh1 {
 | 
			
		||||
    use core::convert::Infallible;
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "nightly")]
 | 
			
		||||
    use futures::FutureExt;
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
 | 
			
		||||
@@ -991,57 +988,57 @@ mod eh1 {
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "nightly")]
 | 
			
		||||
    impl<'d, T: Pin> embedded_hal_async::digital::Wait for Flex<'d, T> {
 | 
			
		||||
        type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
 | 
			
		||||
            self.wait_for_high().map(Ok)
 | 
			
		||||
        async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_high().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
 | 
			
		||||
            self.wait_for_low().map(Ok)
 | 
			
		||||
        async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_low().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_rising_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_rising_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_falling_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_falling_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_any_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_any_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "nightly")]
 | 
			
		||||
    impl<'d, T: Pin> embedded_hal_async::digital::Wait for Input<'d, T> {
 | 
			
		||||
        type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
 | 
			
		||||
            self.wait_for_high().map(Ok)
 | 
			
		||||
        async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_high().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
 | 
			
		||||
            self.wait_for_low().map(Ok)
 | 
			
		||||
        async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_low().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_rising_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_rising_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_falling_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_falling_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_any_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_any_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -717,8 +717,6 @@ mod eh1 {
 | 
			
		||||
}
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
mod nightly {
 | 
			
		||||
    use core::future::Future;
 | 
			
		||||
 | 
			
		||||
    use embedded_hal_1::i2c::Operation;
 | 
			
		||||
    use embedded_hal_async::i2c::AddressMode;
 | 
			
		||||
 | 
			
		||||
@@ -729,74 +727,55 @@ mod nightly {
 | 
			
		||||
        A: AddressMode + Into<u16> + 'static,
 | 
			
		||||
        T: Instance + 'd,
 | 
			
		||||
    {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
            where Self: 'a;
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
            where Self: 'a;
 | 
			
		||||
        type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
            where Self: 'a;
 | 
			
		||||
        type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Error>> + 'a
 | 
			
		||||
            where Self: 'a, 'b: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async fn read<'a>(&'a mut self, address: A, read: &'a mut [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            let addr: u16 = address.into();
 | 
			
		||||
 | 
			
		||||
            async move {
 | 
			
		||||
                Self::setup(addr)?;
 | 
			
		||||
                self.read_async_internal(buffer, false, true).await
 | 
			
		||||
            }
 | 
			
		||||
            Self::setup(addr)?;
 | 
			
		||||
            self.read_async_internal(read, false, true).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            let addr: u16 = address.into();
 | 
			
		||||
 | 
			
		||||
            async move {
 | 
			
		||||
                Self::setup(addr)?;
 | 
			
		||||
                self.write_async_internal(write.iter().copied(), true).await
 | 
			
		||||
            }
 | 
			
		||||
            Self::setup(addr)?;
 | 
			
		||||
            self.write_async_internal(write.iter().copied(), true).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn write_read<'a>(
 | 
			
		||||
        async fn write_read<'a>(
 | 
			
		||||
            &'a mut self,
 | 
			
		||||
            address: A,
 | 
			
		||||
            bytes: &'a [u8],
 | 
			
		||||
            buffer: &'a mut [u8],
 | 
			
		||||
        ) -> Self::WriteReadFuture<'a> {
 | 
			
		||||
            write: &'a [u8],
 | 
			
		||||
            read: &'a mut [u8],
 | 
			
		||||
        ) -> Result<(), Self::Error> {
 | 
			
		||||
            let addr: u16 = address.into();
 | 
			
		||||
 | 
			
		||||
            async move {
 | 
			
		||||
                Self::setup(addr)?;
 | 
			
		||||
                self.write_async_internal(bytes.iter().cloned(), false).await?;
 | 
			
		||||
                self.read_async_internal(buffer, false, true).await
 | 
			
		||||
            }
 | 
			
		||||
            Self::setup(addr)?;
 | 
			
		||||
            self.write_async_internal(write.iter().cloned(), false).await?;
 | 
			
		||||
            self.read_async_internal(read, false, true).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn transaction<'a, 'b>(
 | 
			
		||||
        async fn transaction<'a, 'b>(
 | 
			
		||||
            &'a mut self,
 | 
			
		||||
            address: A,
 | 
			
		||||
            operations: &'a mut [Operation<'b>],
 | 
			
		||||
        ) -> Self::TransactionFuture<'a, 'b> {
 | 
			
		||||
        ) -> Result<(), Self::Error> {
 | 
			
		||||
            let addr: u16 = address.into();
 | 
			
		||||
 | 
			
		||||
            async move {
 | 
			
		||||
                let mut iterator = operations.iter_mut();
 | 
			
		||||
            let mut iterator = operations.iter_mut();
 | 
			
		||||
 | 
			
		||||
                while let Some(op) = iterator.next() {
 | 
			
		||||
                    let last = iterator.len() == 0;
 | 
			
		||||
            while let Some(op) = iterator.next() {
 | 
			
		||||
                let last = iterator.len() == 0;
 | 
			
		||||
 | 
			
		||||
                    match op {
 | 
			
		||||
                        Operation::Read(buffer) => {
 | 
			
		||||
                            Self::setup(addr)?;
 | 
			
		||||
                            self.read_async_internal(buffer, false, last).await?;
 | 
			
		||||
                        }
 | 
			
		||||
                        Operation::Write(buffer) => {
 | 
			
		||||
                            Self::setup(addr)?;
 | 
			
		||||
                            self.write_async_internal(buffer.into_iter().cloned(), last).await?;
 | 
			
		||||
                        }
 | 
			
		||||
                match op {
 | 
			
		||||
                    Operation::Read(buffer) => {
 | 
			
		||||
                        Self::setup(addr)?;
 | 
			
		||||
                        self.read_async_internal(buffer, false, last).await?;
 | 
			
		||||
                    }
 | 
			
		||||
                    Operation::Write(buffer) => {
 | 
			
		||||
                        Self::setup(addr)?;
 | 
			
		||||
                        self.write_async_internal(buffer.into_iter().cloned(), last).await?;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Ok(())
 | 
			
		||||
            }
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#![no_std]
 | 
			
		||||
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
 | 
			
		||||
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
 | 
			
		||||
#![cfg_attr(feature = "nightly", allow(incomplete_features))]
 | 
			
		||||
 | 
			
		||||
// This mod MUST go first, so that the others see its macros.
 | 
			
		||||
pub(crate) mod fmt;
 | 
			
		||||
 
 | 
			
		||||
@@ -554,45 +554,33 @@ mod eh1 {
 | 
			
		||||
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
mod eha {
 | 
			
		||||
    use core::future::Future;
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBusFlush for Spi<'d, T, Async> {
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
            async { Ok(()) }
 | 
			
		||||
        async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBusWrite<u8> for Spi<'d, T, Async> {
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.write(data)
 | 
			
		||||
        async fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.write(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBusRead<u8> for Spi<'d, T, Async> {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.read(data)
 | 
			
		||||
        async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.read(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spi<'d, T, Async> {
 | 
			
		||||
        type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
 | 
			
		||||
            self.transfer(rx, tx)
 | 
			
		||||
        async fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.transfer(read, write).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transfer_in_place<'a>(&'a mut self, words: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> {
 | 
			
		||||
            self.transfer_in_place(words)
 | 
			
		||||
        async fn transfer_in_place<'a>(&'a mut self, words: &'a mut [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.transfer_in_place(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
use core::future::{poll_fn, Future};
 | 
			
		||||
use core::future::poll_fn;
 | 
			
		||||
use core::task::{Poll, Waker};
 | 
			
		||||
 | 
			
		||||
use atomic_polyfill::{compiler_fence, Ordering};
 | 
			
		||||
@@ -355,11 +355,7 @@ impl<'d, T: Instance> embedded_io::Io for BufferedUartTx<'d, T> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            let (res, do_pend) = self.inner.with(|state| {
 | 
			
		||||
                compiler_fence(Ordering::SeqCst);
 | 
			
		||||
@@ -372,15 +368,12 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> {
 | 
			
		||||
 | 
			
		||||
            res
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUartRx<'d, T> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            let (res, do_pend) = self.inner.with(|state| {
 | 
			
		||||
                compiler_fence(Ordering::SeqCst);
 | 
			
		||||
@@ -393,21 +386,19 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUartRx<'d, T> {
 | 
			
		||||
 | 
			
		||||
            res
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T> {
 | 
			
		||||
    type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> {
 | 
			
		||||
    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            self.inner.with(|state| {
 | 
			
		||||
                compiler_fence(Ordering::SeqCst);
 | 
			
		||||
                state.rx.fill_buf(cx.waker())
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn consume(&mut self, amt: usize) {
 | 
			
		||||
@@ -419,17 +410,14 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUartRx<'d, T> {
 | 
			
		||||
    type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> {
 | 
			
		||||
    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            self.inner.with(|state| {
 | 
			
		||||
                compiler_fence(Ordering::SeqCst);
 | 
			
		||||
                state.fill_buf(cx.waker())
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn consume(&mut self, amt: usize) {
 | 
			
		||||
@@ -441,11 +429,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUartRx<'d, T
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            let (poll, empty) = self.inner.with(|state| state.tx.write(buf, cx.waker()));
 | 
			
		||||
            if empty {
 | 
			
		||||
@@ -453,23 +437,16 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> {
 | 
			
		||||
            }
 | 
			
		||||
            poll
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        poll_fn(move |cx| self.inner.with(|state| state.tx.flush(cx.waker())))
 | 
			
		||||
    async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| self.inner.with(|state| state.tx.flush(cx.waker()))).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUartTx<'d, T> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| {
 | 
			
		||||
            let (poll, empty) = self.inner.with(|state| state.write(buf, cx.waker()));
 | 
			
		||||
            if empty {
 | 
			
		||||
@@ -477,13 +454,10 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUartTx<'d, T>
 | 
			
		||||
            }
 | 
			
		||||
            poll
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        poll_fn(move |cx| self.inner.with(|state| state.flush(cx.waker())))
 | 
			
		||||
    async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        poll_fn(move |cx| self.inner.with(|state| state.flush(cx.waker()))).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
use core::future::{poll_fn, Future};
 | 
			
		||||
use core::future::poll_fn;
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use core::slice;
 | 
			
		||||
use core::sync::atomic::Ordering;
 | 
			
		||||
@@ -352,9 +352,7 @@ pub struct Bus<'d, T: Instance> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
			
		||||
    type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn poll<'a>(&'a mut self) -> Self::PollFuture<'a> {
 | 
			
		||||
    async fn poll(&mut self) -> Event {
 | 
			
		||||
        poll_fn(move |cx| unsafe {
 | 
			
		||||
            BUS_WAKER.register(cx.waker());
 | 
			
		||||
 | 
			
		||||
@@ -406,6 +404,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
			
		||||
            });
 | 
			
		||||
            Poll::Pending
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
@@ -456,22 +455,12 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
    async fn enable(&mut self) {}
 | 
			
		||||
 | 
			
		||||
    fn enable(&mut self) -> Self::EnableFuture<'_> {
 | 
			
		||||
        async move {}
 | 
			
		||||
    }
 | 
			
		||||
    async fn disable(&mut self) {}
 | 
			
		||||
 | 
			
		||||
    type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn disable(&mut self) -> Self::DisableFuture<'_> {
 | 
			
		||||
        async move {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type RemoteWakeupFuture<'a> =  impl Future<Output = Result<(), Unsupported>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_> {
 | 
			
		||||
        async move { Err(Unsupported) }
 | 
			
		||||
    async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
 | 
			
		||||
        Err(Unsupported)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -515,24 +504,20 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> {
 | 
			
		||||
        &self.info
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("wait_enabled IN WAITING");
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_IN_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() };
 | 
			
		||||
                if val.enable() {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
            trace!("wait_enabled IN OK");
 | 
			
		||||
        }
 | 
			
		||||
    async fn wait_enabled(&mut self) {
 | 
			
		||||
        trace!("wait_enabled IN WAITING");
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_IN_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let val = unsafe { T::dpram().ep_in_control(self.info.addr.index() - 1).read() };
 | 
			
		||||
            if val.enable() {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
        trace!("wait_enabled IN OK");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -541,117 +526,105 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, Out> {
 | 
			
		||||
        &self.info
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("wait_enabled OUT WAITING");
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let val = unsafe { T::dpram().ep_out_control(self.info.addr.index() - 1).read() };
 | 
			
		||||
                if val.enable() {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
            trace!("wait_enabled OUT OK");
 | 
			
		||||
        }
 | 
			
		||||
    async fn wait_enabled(&mut self) {
 | 
			
		||||
        trace!("wait_enabled OUT WAITING");
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let val = unsafe { T::dpram().ep_out_control(self.info.addr.index() - 1).read() };
 | 
			
		||||
            if val.enable() {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
        trace!("wait_enabled OUT OK");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("READ WAITING, buf.len() = {}", buf.len());
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
            let val = poll_fn(|cx| unsafe {
 | 
			
		||||
                EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let val = T::dpram().ep_out_buffer_control(index).read();
 | 
			
		||||
                if val.available(0) {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Ready(val)
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
            let rx_len = val.length(0) as usize;
 | 
			
		||||
            if rx_len > buf.len() {
 | 
			
		||||
                return Err(EndpointError::BufferOverflow);
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
 | 
			
		||||
        trace!("READ WAITING, buf.len() = {}", buf.len());
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
        let val = poll_fn(|cx| unsafe {
 | 
			
		||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let val = T::dpram().ep_out_buffer_control(index).read();
 | 
			
		||||
            if val.available(0) {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Ready(val)
 | 
			
		||||
            }
 | 
			
		||||
            self.buf.read(&mut buf[..rx_len]);
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
            trace!("READ OK, rx_len = {}", rx_len);
 | 
			
		||||
 | 
			
		||||
            unsafe {
 | 
			
		||||
                let pid = !val.pid(0);
 | 
			
		||||
                T::dpram().ep_out_buffer_control(index).write(|w| {
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                    w.set_length(0, self.info.max_packet_size);
 | 
			
		||||
                });
 | 
			
		||||
                cortex_m::asm::delay(12);
 | 
			
		||||
                T::dpram().ep_out_buffer_control(index).write(|w| {
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                    w.set_length(0, self.info.max_packet_size);
 | 
			
		||||
                    w.set_available(0, true);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Ok(rx_len)
 | 
			
		||||
        let rx_len = val.length(0) as usize;
 | 
			
		||||
        if rx_len > buf.len() {
 | 
			
		||||
            return Err(EndpointError::BufferOverflow);
 | 
			
		||||
        }
 | 
			
		||||
        self.buf.read(&mut buf[..rx_len]);
 | 
			
		||||
 | 
			
		||||
        trace!("READ OK, rx_len = {}", rx_len);
 | 
			
		||||
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let pid = !val.pid(0);
 | 
			
		||||
            T::dpram().ep_out_buffer_control(index).write(|w| {
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
                w.set_length(0, self.info.max_packet_size);
 | 
			
		||||
            });
 | 
			
		||||
            cortex_m::asm::delay(12);
 | 
			
		||||
            T::dpram().ep_out_buffer_control(index).write(|w| {
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
                w.set_length(0, self.info.max_packet_size);
 | 
			
		||||
                w.set_available(0, true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(rx_len)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            if buf.len() > self.info.max_packet_size as usize {
 | 
			
		||||
                return Err(EndpointError::BufferOverflow);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            trace!("WRITE WAITING");
 | 
			
		||||
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
            let val = poll_fn(|cx| unsafe {
 | 
			
		||||
                EP_IN_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let val = T::dpram().ep_in_buffer_control(index).read();
 | 
			
		||||
                if val.available(0) {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Ready(val)
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
            self.buf.write(buf);
 | 
			
		||||
 | 
			
		||||
            unsafe {
 | 
			
		||||
                let pid = !val.pid(0);
 | 
			
		||||
                T::dpram().ep_in_buffer_control(index).write(|w| {
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                    w.set_length(0, buf.len() as _);
 | 
			
		||||
                    w.set_full(0, true);
 | 
			
		||||
                });
 | 
			
		||||
                cortex_m::asm::delay(12);
 | 
			
		||||
                T::dpram().ep_in_buffer_control(index).write(|w| {
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                    w.set_length(0, buf.len() as _);
 | 
			
		||||
                    w.set_full(0, true);
 | 
			
		||||
                    w.set_available(0, true);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            trace!("WRITE OK");
 | 
			
		||||
 | 
			
		||||
            Ok(())
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> {
 | 
			
		||||
        if buf.len() > self.info.max_packet_size as usize {
 | 
			
		||||
            return Err(EndpointError::BufferOverflow);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        trace!("WRITE WAITING");
 | 
			
		||||
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
        let val = poll_fn(|cx| unsafe {
 | 
			
		||||
            EP_IN_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let val = T::dpram().ep_in_buffer_control(index).read();
 | 
			
		||||
            if val.available(0) {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Ready(val)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
        self.buf.write(buf);
 | 
			
		||||
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let pid = !val.pid(0);
 | 
			
		||||
            T::dpram().ep_in_buffer_control(index).write(|w| {
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
                w.set_length(0, buf.len() as _);
 | 
			
		||||
                w.set_full(0, true);
 | 
			
		||||
            });
 | 
			
		||||
            cortex_m::asm::delay(12);
 | 
			
		||||
            T::dpram().ep_in_buffer_control(index).write(|w| {
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
                w.set_length(0, buf.len() as _);
 | 
			
		||||
                w.set_full(0, true);
 | 
			
		||||
                w.set_available(0, true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        trace!("WRITE OK");
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -661,199 +634,183 @@ pub struct ControlPipe<'d, T: Instance> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
			
		||||
    type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a;
 | 
			
		||||
    type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    type AcceptFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
    type RejectFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn max_packet_size(&self) -> usize {
 | 
			
		||||
        64
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            loop {
 | 
			
		||||
                trace!("SETUP read waiting");
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                unsafe { regs.inte().write_set(|w| w.set_setup_req(true)) };
 | 
			
		||||
 | 
			
		||||
                poll_fn(|cx| unsafe {
 | 
			
		||||
                    EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
                    let regs = T::regs();
 | 
			
		||||
                    if regs.sie_status().read().setup_rec() {
 | 
			
		||||
                        Poll::Ready(())
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Poll::Pending
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .await;
 | 
			
		||||
 | 
			
		||||
                let mut buf = [0; 8];
 | 
			
		||||
                EndpointBuffer::<T>::new(0, 8).read(&mut buf);
 | 
			
		||||
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                unsafe {
 | 
			
		||||
                    regs.sie_status().write(|w| w.set_setup_rec(true));
 | 
			
		||||
 | 
			
		||||
                    // set PID to 0, so (after toggling) first DATA is PID 1
 | 
			
		||||
                    T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
			
		||||
                    T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                trace!("SETUP read ok");
 | 
			
		||||
                return buf;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn data_out<'a>(&'a mut self, buf: &'a mut [u8], _first: bool, _last: bool) -> Self::DataOutFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            unsafe {
 | 
			
		||||
                let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
			
		||||
                let pid = !bufcontrol.read().pid(0);
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, self.max_packet_size);
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                });
 | 
			
		||||
                cortex_m::asm::delay(12);
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, self.max_packet_size);
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                    w.set_available(0, true);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            trace!("control: data_out len={} first={} last={}", buf.len(), _first, _last);
 | 
			
		||||
            let val = poll_fn(|cx| unsafe {
 | 
			
		||||
                EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
                let val = T::dpram().ep_out_buffer_control(0).read();
 | 
			
		||||
                if val.available(0) {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Ready(val)
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
            let rx_len = val.length(0) as _;
 | 
			
		||||
            trace!("control data_out DONE, rx_len = {}", rx_len);
 | 
			
		||||
 | 
			
		||||
            if rx_len > buf.len() {
 | 
			
		||||
                return Err(EndpointError::BufferOverflow);
 | 
			
		||||
            }
 | 
			
		||||
            EndpointBuffer::<T>::new(0x100, 64).read(&mut buf[..rx_len]);
 | 
			
		||||
 | 
			
		||||
            Ok(rx_len)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn data_in<'a>(&'a mut self, buf: &'a [u8], _first: bool, _last: bool) -> Self::DataInFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("control: data_in len={} first={} last={}", buf.len(), _first, _last);
 | 
			
		||||
 | 
			
		||||
            if buf.len() > 64 {
 | 
			
		||||
                return Err(EndpointError::BufferOverflow);
 | 
			
		||||
            }
 | 
			
		||||
            EndpointBuffer::<T>::new(0x100, 64).write(buf);
 | 
			
		||||
 | 
			
		||||
            unsafe {
 | 
			
		||||
                let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
			
		||||
                let pid = !bufcontrol.read().pid(0);
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, buf.len() as _);
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                    w.set_full(0, true);
 | 
			
		||||
                });
 | 
			
		||||
                cortex_m::asm::delay(12);
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, buf.len() as _);
 | 
			
		||||
                    w.set_pid(0, pid);
 | 
			
		||||
                    w.set_full(0, true);
 | 
			
		||||
                    w.set_available(0, true);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
    async fn setup<'a>(&'a mut self) -> [u8; 8] {
 | 
			
		||||
        loop {
 | 
			
		||||
            trace!("SETUP read waiting");
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            unsafe { regs.inte().write_set(|w| w.set_setup_req(true)) };
 | 
			
		||||
 | 
			
		||||
            poll_fn(|cx| unsafe {
 | 
			
		||||
                EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
                let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
			
		||||
                if bufcontrol.read().available(0) {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                } else {
 | 
			
		||||
                EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if regs.sie_status().read().setup_rec() {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
            trace!("control: data_in DONE");
 | 
			
		||||
 | 
			
		||||
            if _last {
 | 
			
		||||
                // prepare status phase right away.
 | 
			
		||||
                unsafe {
 | 
			
		||||
                    let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
			
		||||
                    bufcontrol.write(|w| {
 | 
			
		||||
                        w.set_length(0, 0);
 | 
			
		||||
                        w.set_pid(0, true);
 | 
			
		||||
                    });
 | 
			
		||||
                    cortex_m::asm::delay(12);
 | 
			
		||||
                    bufcontrol.write(|w| {
 | 
			
		||||
                        w.set_length(0, 0);
 | 
			
		||||
                        w.set_pid(0, true);
 | 
			
		||||
                        w.set_available(0, true);
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("control: accept");
 | 
			
		||||
 | 
			
		||||
            let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
			
		||||
            unsafe {
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, 0);
 | 
			
		||||
                    w.set_pid(0, true);
 | 
			
		||||
                    w.set_full(0, true);
 | 
			
		||||
                });
 | 
			
		||||
                cortex_m::asm::delay(12);
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, 0);
 | 
			
		||||
                    w.set_pid(0, true);
 | 
			
		||||
                    w.set_full(0, true);
 | 
			
		||||
                    w.set_available(0, true);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // wait for completion before returning, needed so
 | 
			
		||||
            // set_address() doesn't happen early.
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
                if unsafe { bufcontrol.read().available(0) } {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("control: reject");
 | 
			
		||||
            let mut buf = [0; 8];
 | 
			
		||||
            EndpointBuffer::<T>::new(0, 8).read(&mut buf);
 | 
			
		||||
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            unsafe {
 | 
			
		||||
                regs.ep_stall_arm().write_set(|w| {
 | 
			
		||||
                    w.set_ep0_in(true);
 | 
			
		||||
                    w.set_ep0_out(true);
 | 
			
		||||
                });
 | 
			
		||||
                T::dpram().ep_out_buffer_control(0).write(|w| w.set_stall(true));
 | 
			
		||||
                T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true));
 | 
			
		||||
                regs.sie_status().write(|w| w.set_setup_rec(true));
 | 
			
		||||
 | 
			
		||||
                // set PID to 0, so (after toggling) first DATA is PID 1
 | 
			
		||||
                T::dpram().ep_in_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
			
		||||
                T::dpram().ep_out_buffer_control(0).write(|w| w.set_pid(0, false));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            trace!("SETUP read ok");
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError> {
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
			
		||||
            let pid = !bufcontrol.read().pid(0);
 | 
			
		||||
            bufcontrol.write(|w| {
 | 
			
		||||
                w.set_length(0, self.max_packet_size);
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
            });
 | 
			
		||||
            cortex_m::asm::delay(12);
 | 
			
		||||
            bufcontrol.write(|w| {
 | 
			
		||||
                w.set_length(0, self.max_packet_size);
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
                w.set_available(0, true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        trace!("control: data_out len={} first={} last={}", buf.len(), first, last);
 | 
			
		||||
        let val = poll_fn(|cx| unsafe {
 | 
			
		||||
            EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
            let val = T::dpram().ep_out_buffer_control(0).read();
 | 
			
		||||
            if val.available(0) {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Ready(val)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
        let rx_len = val.length(0) as _;
 | 
			
		||||
        trace!("control data_out DONE, rx_len = {}", rx_len);
 | 
			
		||||
 | 
			
		||||
        if rx_len > buf.len() {
 | 
			
		||||
            return Err(EndpointError::BufferOverflow);
 | 
			
		||||
        }
 | 
			
		||||
        EndpointBuffer::<T>::new(0x100, 64).read(&mut buf[..rx_len]);
 | 
			
		||||
 | 
			
		||||
        Ok(rx_len)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn data_in(&mut self, data: &[u8], first: bool, last: bool) -> Result<(), EndpointError> {
 | 
			
		||||
        trace!("control: data_in len={} first={} last={}", data.len(), first, last);
 | 
			
		||||
 | 
			
		||||
        if data.len() > 64 {
 | 
			
		||||
            return Err(EndpointError::BufferOverflow);
 | 
			
		||||
        }
 | 
			
		||||
        EndpointBuffer::<T>::new(0x100, 64).write(data);
 | 
			
		||||
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
			
		||||
            let pid = !bufcontrol.read().pid(0);
 | 
			
		||||
            bufcontrol.write(|w| {
 | 
			
		||||
                w.set_length(0, data.len() as _);
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
                w.set_full(0, true);
 | 
			
		||||
            });
 | 
			
		||||
            cortex_m::asm::delay(12);
 | 
			
		||||
            bufcontrol.write(|w| {
 | 
			
		||||
                w.set_length(0, data.len() as _);
 | 
			
		||||
                w.set_pid(0, pid);
 | 
			
		||||
                w.set_full(0, true);
 | 
			
		||||
                w.set_available(0, true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        poll_fn(|cx| unsafe {
 | 
			
		||||
            EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
            let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
			
		||||
            if bufcontrol.read().available(0) {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
        trace!("control: data_in DONE");
 | 
			
		||||
 | 
			
		||||
        if last {
 | 
			
		||||
            // prepare status phase right away.
 | 
			
		||||
            unsafe {
 | 
			
		||||
                let bufcontrol = T::dpram().ep_out_buffer_control(0);
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, 0);
 | 
			
		||||
                    w.set_pid(0, true);
 | 
			
		||||
                });
 | 
			
		||||
                cortex_m::asm::delay(12);
 | 
			
		||||
                bufcontrol.write(|w| {
 | 
			
		||||
                    w.set_length(0, 0);
 | 
			
		||||
                    w.set_pid(0, true);
 | 
			
		||||
                    w.set_available(0, true);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn accept(&mut self) {
 | 
			
		||||
        trace!("control: accept");
 | 
			
		||||
 | 
			
		||||
        let bufcontrol = T::dpram().ep_in_buffer_control(0);
 | 
			
		||||
        unsafe {
 | 
			
		||||
            bufcontrol.write(|w| {
 | 
			
		||||
                w.set_length(0, 0);
 | 
			
		||||
                w.set_pid(0, true);
 | 
			
		||||
                w.set_full(0, true);
 | 
			
		||||
            });
 | 
			
		||||
            cortex_m::asm::delay(12);
 | 
			
		||||
            bufcontrol.write(|w| {
 | 
			
		||||
                w.set_length(0, 0);
 | 
			
		||||
                w.set_pid(0, true);
 | 
			
		||||
                w.set_full(0, true);
 | 
			
		||||
                w.set_available(0, true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // wait for completion before returning, needed so
 | 
			
		||||
        // set_address() doesn't happen early.
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
            if unsafe { bufcontrol.read().available(0) } {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn reject(&mut self) {
 | 
			
		||||
        trace!("control: reject");
 | 
			
		||||
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        unsafe {
 | 
			
		||||
            regs.ep_stall_arm().write_set(|w| {
 | 
			
		||||
                w.set_ep0_in(true);
 | 
			
		||||
                w.set_ep0_out(true);
 | 
			
		||||
            });
 | 
			
		||||
            T::dpram().ep_out_buffer_control(0).write(|w| w.set_stall(true));
 | 
			
		||||
            T::dpram().ep_in_buffer_control(0).write(|w| w.set_stall(true));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optiona
 | 
			
		||||
 | 
			
		||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9", optional = true}
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3", optional = true}
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true}
 | 
			
		||||
embedded-hal-nb = { version = "=1.0.0-alpha.1", optional = true}
 | 
			
		||||
 | 
			
		||||
embedded-storage = "0.3.0"
 | 
			
		||||
@@ -67,7 +67,7 @@ nb = "1.0.0"
 | 
			
		||||
stm32-fmc = "0.2.4"
 | 
			
		||||
seq-macro = "0.3.0"
 | 
			
		||||
cfg-if = "1.0.0"
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async"], optional = true }
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
proc-macro2 = "1.0.36"
 | 
			
		||||
 
 | 
			
		||||
@@ -167,39 +167,33 @@ mod eh1 {
 | 
			
		||||
}
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
mod eha {
 | 
			
		||||
    use futures::FutureExt;
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> {
 | 
			
		||||
        type WaitForHighFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
 | 
			
		||||
            self.wait_for_high().map(Ok)
 | 
			
		||||
        async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_high().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForLowFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
 | 
			
		||||
            self.wait_for_low().map(Ok)
 | 
			
		||||
        async fn wait_for_low(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_low().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForRisingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_rising_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_rising_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_rising_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForFallingEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_falling_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_falling_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_falling_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WaitForAnyEdgeFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
 | 
			
		||||
            self.wait_for_any_edge().map(Ok)
 | 
			
		||||
        async fn wait_for_any_edge(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            self.wait_for_any_edge().await;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1048,43 +1048,35 @@ mod eh1 {
 | 
			
		||||
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
mod eha {
 | 
			
		||||
    use core::future::Future;
 | 
			
		||||
 | 
			
		||||
    use super::super::{RxDma, TxDma};
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c for I2c<'d, T, TXDMA, RXDMA> {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.read(address, buffer)
 | 
			
		||||
        async fn read<'a>(&'a mut self, address: u8, read: &'a mut [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.read(address, read).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.write(address, bytes)
 | 
			
		||||
        async fn write<'a>(&'a mut self, address: u8, write: &'a [u8]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.write(address, write).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
        fn write_read<'a>(
 | 
			
		||||
        async fn write_read<'a>(
 | 
			
		||||
            &'a mut self,
 | 
			
		||||
            address: u8,
 | 
			
		||||
            bytes: &'a [u8],
 | 
			
		||||
            buffer: &'a mut [u8],
 | 
			
		||||
        ) -> Self::WriteReadFuture<'a> {
 | 
			
		||||
            self.write_read(address, bytes, buffer)
 | 
			
		||||
            write: &'a [u8],
 | 
			
		||||
            read: &'a mut [u8],
 | 
			
		||||
        ) -> Result<(), Self::Error> {
 | 
			
		||||
            self.write_read(address, write, read).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transaction<'a, 'b>(
 | 
			
		||||
        async fn transaction<'a, 'b>(
 | 
			
		||||
            &'a mut self,
 | 
			
		||||
            address: u8,
 | 
			
		||||
            operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
 | 
			
		||||
        ) -> Self::TransactionFuture<'a, 'b> {
 | 
			
		||||
            operations: &'a mut [embedded_hal_1::i2c::Operation<'b>],
 | 
			
		||||
        ) -> Result<(), Self::Error> {
 | 
			
		||||
            let _ = address;
 | 
			
		||||
            let _ = operations;
 | 
			
		||||
            async move { todo!() }
 | 
			
		||||
            todo!()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
#![no_std]
 | 
			
		||||
#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))]
 | 
			
		||||
#![cfg_attr(
 | 
			
		||||
    feature = "nightly",
 | 
			
		||||
    feature(type_alias_impl_trait, async_fn_in_trait, impl_trait_projections)
 | 
			
		||||
)]
 | 
			
		||||
#![cfg_attr(feature = "nightly", allow(incomplete_features))]
 | 
			
		||||
 | 
			
		||||
// This must go FIRST so that all the other modules see its macros.
 | 
			
		||||
pub mod fmt;
 | 
			
		||||
 
 | 
			
		||||
@@ -885,46 +885,34 @@ mod eh1 {
 | 
			
		||||
 | 
			
		||||
#[cfg(all(feature = "unstable-traits", feature = "nightly"))]
 | 
			
		||||
mod eha {
 | 
			
		||||
    use core::future::Future;
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
    impl<'d, T: Instance, Tx, Rx> embedded_hal_async::spi::SpiBusFlush for Spi<'d, T, Tx, Rx> {
 | 
			
		||||
        type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
            async { Ok(()) }
 | 
			
		||||
        async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance, Tx: TxDma<T>, Rx, W: Word> embedded_hal_async::spi::SpiBusWrite<W> for Spi<'d, T, Tx, Rx> {
 | 
			
		||||
        type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn write<'a>(&'a mut self, data: &'a [W]) -> Self::WriteFuture<'a> {
 | 
			
		||||
            self.write(data)
 | 
			
		||||
        async fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.write(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::spi::SpiBusRead<W>
 | 
			
		||||
        for Spi<'d, T, Tx, Rx>
 | 
			
		||||
    {
 | 
			
		||||
        type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn read<'a>(&'a mut self, data: &'a mut [W]) -> Self::ReadFuture<'a> {
 | 
			
		||||
            self.read(data)
 | 
			
		||||
        async fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.read(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::spi::SpiBus<W> for Spi<'d, T, Tx, Rx> {
 | 
			
		||||
        type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transfer<'a>(&'a mut self, rx: &'a mut [W], tx: &'a [W]) -> Self::TransferFuture<'a> {
 | 
			
		||||
            self.transfer(rx, tx)
 | 
			
		||||
        async fn transfer<'a>(&'a mut self, read: &'a mut [W], write: &'a [W]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.transfer(read, write).await
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type TransferInPlaceFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
        fn transfer_in_place<'a>(&'a mut self, words: &'a mut [W]) -> Self::TransferInPlaceFuture<'a> {
 | 
			
		||||
            self.transfer_in_place(words)
 | 
			
		||||
        async fn transfer_in_place<'a>(&'a mut self, words: &'a mut [W]) -> Result<(), Self::Error> {
 | 
			
		||||
            self.transfer_in_place(words).await
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
use core::cell::RefCell;
 | 
			
		||||
use core::future::{poll_fn, Future};
 | 
			
		||||
use core::future::poll_fn;
 | 
			
		||||
use core::task::Poll;
 | 
			
		||||
 | 
			
		||||
use atomic_polyfill::{compiler_fence, Ordering};
 | 
			
		||||
@@ -339,32 +339,20 @@ impl<'u, 'd, T: BasicInstance> embedded_io::Io for BufferedUartTx<'u, 'd, T> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: BasicInstance> embedded_io::asynch::Read for BufferedUart<'d, T> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        self.inner_read(buf)
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner_read(buf).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'u, 'd, T: BasicInstance> embedded_io::asynch::Read for BufferedUartRx<'u, 'd, T> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        self.inner.inner_read(buf)
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner.inner_read(buf).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUart<'d, T> {
 | 
			
		||||
    type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> {
 | 
			
		||||
        self.inner_fill_buf()
 | 
			
		||||
    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
 | 
			
		||||
        self.inner_fill_buf().await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn consume(&mut self, amt: usize) {
 | 
			
		||||
@@ -373,12 +361,8 @@ impl<'d, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUart<'d, T>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'u, 'd, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUartRx<'u, 'd, T> {
 | 
			
		||||
    type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> {
 | 
			
		||||
        self.inner.inner_fill_buf()
 | 
			
		||||
    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
 | 
			
		||||
        self.inner.inner_fill_buf().await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn consume(&mut self, amt: usize) {
 | 
			
		||||
@@ -387,37 +371,21 @@ impl<'u, 'd, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUartRx<'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: BasicInstance> embedded_io::asynch::Write for BufferedUart<'d, T> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        self.inner_write(buf)
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner_write(buf).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        self.inner_flush()
 | 
			
		||||
    async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        self.inner_flush().await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'u, 'd, T: BasicInstance> embedded_io::asynch::Write for BufferedUartTx<'u, 'd, T> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        self.inner.inner_write(buf)
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
 | 
			
		||||
        self.inner.inner_write(buf).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
 | 
			
		||||
        self.inner.inner_flush()
 | 
			
		||||
    async fn flush(&mut self) -> Result<(), Self::Error> {
 | 
			
		||||
        self.inner.inner_flush().await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#![macro_use]
 | 
			
		||||
 | 
			
		||||
use core::future::{poll_fn, Future};
 | 
			
		||||
use core::future::poll_fn;
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use core::sync::atomic::Ordering;
 | 
			
		||||
use core::task::Poll;
 | 
			
		||||
@@ -429,9 +429,7 @@ pub struct Bus<'d, T: Instance> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
			
		||||
    type PollFuture<'a> = impl Future<Output = Event> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn poll<'a>(&'a mut self) -> Self::PollFuture<'a> {
 | 
			
		||||
    async fn poll(&mut self) -> Event {
 | 
			
		||||
        poll_fn(move |cx| unsafe {
 | 
			
		||||
            BUS_WAKER.register(cx.waker());
 | 
			
		||||
 | 
			
		||||
@@ -488,6 +486,7 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
			
		||||
                return Poll::Ready(Event::PowerDetected);
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
@@ -598,22 +597,11 @@ impl<'d, T: Instance> driver::Bus for Bus<'d, T> {
 | 
			
		||||
        trace!("EPR after: {:04x}", unsafe { reg.read() }.0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type EnableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
    async fn enable(&mut self) {}
 | 
			
		||||
    async fn disable(&mut self) {}
 | 
			
		||||
 | 
			
		||||
    fn enable(&mut self) -> Self::EnableFuture<'_> {
 | 
			
		||||
        async move {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type DisableFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn disable(&mut self) -> Self::DisableFuture<'_> {
 | 
			
		||||
        async move {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type RemoteWakeupFuture<'a> =  impl Future<Output = Result<(), Unsupported>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_> {
 | 
			
		||||
        async move { Err(Unsupported) }
 | 
			
		||||
    async fn remote_wakeup(&mut self) -> Result<(), Unsupported> {
 | 
			
		||||
        Err(Unsupported)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -676,24 +664,20 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> {
 | 
			
		||||
        &self.info
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("wait_enabled OUT WAITING");
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if unsafe { regs.epr(index).read() }.stat_tx() == Stat::DISABLED {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
            trace!("wait_enabled OUT OK");
 | 
			
		||||
        }
 | 
			
		||||
    async fn wait_enabled(&mut self) {
 | 
			
		||||
        trace!("wait_enabled OUT WAITING");
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            if unsafe { regs.epr(index).read() }.stat_tx() == Stat::DISABLED {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
        trace!("wait_enabled OUT OK");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -702,116 +686,104 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, Out> {
 | 
			
		||||
        &self.info
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    type WaitEnabledFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("wait_enabled OUT WAITING");
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if unsafe { regs.epr(index).read() }.stat_rx() == Stat::DISABLED {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
            trace!("wait_enabled OUT OK");
 | 
			
		||||
        }
 | 
			
		||||
    async fn wait_enabled(&mut self) {
 | 
			
		||||
        trace!("wait_enabled OUT WAITING");
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            if unsafe { regs.epr(index).read() }.stat_rx() == Stat::DISABLED {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
        trace!("wait_enabled OUT OK");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> {
 | 
			
		||||
    type ReadFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("READ WAITING, buf.len() = {}", buf.len());
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
            let stat = poll_fn(|cx| {
 | 
			
		||||
                EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                let stat = unsafe { regs.epr(index).read() }.stat_rx();
 | 
			
		||||
                if matches!(stat, Stat::NAK | Stat::DISABLED) {
 | 
			
		||||
                    Poll::Ready(stat)
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
            if stat == Stat::DISABLED {
 | 
			
		||||
                return Err(EndpointError::Disabled);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let rx_len = self.read_data(buf)?;
 | 
			
		||||
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> {
 | 
			
		||||
        trace!("READ WAITING, buf.len() = {}", buf.len());
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
        let stat = poll_fn(|cx| {
 | 
			
		||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            unsafe {
 | 
			
		||||
                regs.epr(index).write(|w| {
 | 
			
		||||
                    w.set_ep_type(convert_type(self.info.ep_type));
 | 
			
		||||
                    w.set_ea(self.info.addr.index() as _);
 | 
			
		||||
                    w.set_stat_rx(Stat(Stat::NAK.0 ^ Stat::VALID.0));
 | 
			
		||||
                    w.set_stat_tx(Stat(0));
 | 
			
		||||
                    w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                    w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                })
 | 
			
		||||
            };
 | 
			
		||||
            trace!("READ OK, rx_len = {}", rx_len);
 | 
			
		||||
            let stat = unsafe { regs.epr(index).read() }.stat_rx();
 | 
			
		||||
            if matches!(stat, Stat::NAK | Stat::DISABLED) {
 | 
			
		||||
                Poll::Ready(stat)
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
            Ok(rx_len)
 | 
			
		||||
        if stat == Stat::DISABLED {
 | 
			
		||||
            return Err(EndpointError::Disabled);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let rx_len = self.read_data(buf)?;
 | 
			
		||||
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        unsafe {
 | 
			
		||||
            regs.epr(index).write(|w| {
 | 
			
		||||
                w.set_ep_type(convert_type(self.info.ep_type));
 | 
			
		||||
                w.set_ea(self.info.addr.index() as _);
 | 
			
		||||
                w.set_stat_rx(Stat(Stat::NAK.0 ^ Stat::VALID.0));
 | 
			
		||||
                w.set_stat_tx(Stat(0));
 | 
			
		||||
                w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                w.set_ctr_tx(true); // don't clear
 | 
			
		||||
            })
 | 
			
		||||
        };
 | 
			
		||||
        trace!("READ OK, rx_len = {}", rx_len);
 | 
			
		||||
 | 
			
		||||
        Ok(rx_len)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> {
 | 
			
		||||
    type WriteFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            if buf.len() > self.info.max_packet_size as usize {
 | 
			
		||||
                return Err(EndpointError::BufferOverflow);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let index = self.info.addr.index();
 | 
			
		||||
 | 
			
		||||
            trace!("WRITE WAITING");
 | 
			
		||||
            let stat = poll_fn(|cx| {
 | 
			
		||||
                EP_IN_WAKERS[index].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                let stat = unsafe { regs.epr(index).read() }.stat_tx();
 | 
			
		||||
                if matches!(stat, Stat::NAK | Stat::DISABLED) {
 | 
			
		||||
                    Poll::Ready(stat)
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
            if stat == Stat::DISABLED {
 | 
			
		||||
                return Err(EndpointError::Disabled);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            self.write_data(buf);
 | 
			
		||||
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            unsafe {
 | 
			
		||||
                regs.epr(index).write(|w| {
 | 
			
		||||
                    w.set_ep_type(convert_type(self.info.ep_type));
 | 
			
		||||
                    w.set_ea(self.info.addr.index() as _);
 | 
			
		||||
                    w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0));
 | 
			
		||||
                    w.set_stat_rx(Stat(0));
 | 
			
		||||
                    w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                    w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                })
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            trace!("WRITE OK");
 | 
			
		||||
 | 
			
		||||
            Ok(())
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> {
 | 
			
		||||
        if buf.len() > self.info.max_packet_size as usize {
 | 
			
		||||
            return Err(EndpointError::BufferOverflow);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let index = self.info.addr.index();
 | 
			
		||||
 | 
			
		||||
        trace!("WRITE WAITING");
 | 
			
		||||
        let stat = poll_fn(|cx| {
 | 
			
		||||
            EP_IN_WAKERS[index].register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            let stat = unsafe { regs.epr(index).read() }.stat_tx();
 | 
			
		||||
            if matches!(stat, Stat::NAK | Stat::DISABLED) {
 | 
			
		||||
                Poll::Ready(stat)
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
        if stat == Stat::DISABLED {
 | 
			
		||||
            return Err(EndpointError::Disabled);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.write_data(buf);
 | 
			
		||||
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        unsafe {
 | 
			
		||||
            regs.epr(index).write(|w| {
 | 
			
		||||
                w.set_ep_type(convert_type(self.info.ep_type));
 | 
			
		||||
                w.set_ea(self.info.addr.index() as _);
 | 
			
		||||
                w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0));
 | 
			
		||||
                w.set_stat_rx(Stat(0));
 | 
			
		||||
                w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                w.set_ctr_tx(true); // don't clear
 | 
			
		||||
            })
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        trace!("WRITE OK");
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -823,84 +795,16 @@ pub struct ControlPipe<'d, T: Instance> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
			
		||||
    type SetupFuture<'a> = impl Future<Output = [u8;8]> + 'a where Self: 'a;
 | 
			
		||||
    type DataOutFuture<'a> = impl Future<Output = Result<usize, EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    type DataInFuture<'a> = impl Future<Output = Result<(), EndpointError>> + 'a where Self: 'a;
 | 
			
		||||
    type AcceptFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
    type RejectFuture<'a> = impl Future<Output = ()> + 'a where Self: 'a;
 | 
			
		||||
 | 
			
		||||
    fn max_packet_size(&self) -> usize {
 | 
			
		||||
        usize::from(self.max_packet_size)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            loop {
 | 
			
		||||
                trace!("SETUP read waiting");
 | 
			
		||||
                poll_fn(|cx| {
 | 
			
		||||
                    EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
                    if EP0_SETUP.load(Ordering::Relaxed) {
 | 
			
		||||
                        Poll::Ready(())
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Poll::Pending
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .await;
 | 
			
		||||
 | 
			
		||||
                let mut buf = [0; 8];
 | 
			
		||||
                let rx_len = self.ep_out.read_data(&mut buf);
 | 
			
		||||
                if rx_len != Ok(8) {
 | 
			
		||||
                    trace!("SETUP read failed: {:?}", rx_len);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                EP0_SETUP.store(false, Ordering::Relaxed);
 | 
			
		||||
 | 
			
		||||
                trace!("SETUP read ok");
 | 
			
		||||
                return buf;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn data_out<'a>(&'a mut self, buf: &'a mut [u8], first: bool, last: bool) -> Self::DataOutFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
            // When a SETUP is received, Stat/Stat is set to NAK.
 | 
			
		||||
            // On first transfer, we must set Stat=VALID, to get the OUT data stage.
 | 
			
		||||
            // We want Stat=STALL so that the host gets a STALL if it switches to the status
 | 
			
		||||
            // stage too soon, except in the last transfer we set Stat=NAK so that it waits
 | 
			
		||||
            // for the status stage, which we will ACK or STALL later.
 | 
			
		||||
            if first || last {
 | 
			
		||||
                let mut stat_rx = 0;
 | 
			
		||||
                let mut stat_tx = 0;
 | 
			
		||||
                if first {
 | 
			
		||||
                    // change NAK -> VALID
 | 
			
		||||
                    stat_rx ^= Stat::NAK.0 ^ Stat::VALID.0;
 | 
			
		||||
                    stat_tx ^= Stat::NAK.0 ^ Stat::STALL.0;
 | 
			
		||||
                }
 | 
			
		||||
                if last {
 | 
			
		||||
                    // change STALL -> VALID
 | 
			
		||||
                    stat_tx ^= Stat::STALL.0 ^ Stat::NAK.0;
 | 
			
		||||
                }
 | 
			
		||||
                // Note: if this is the first AND last transfer, the above effectively
 | 
			
		||||
                // changes stat_tx like NAK -> NAK, so noop.
 | 
			
		||||
                unsafe {
 | 
			
		||||
                    regs.epr(0).write(|w| {
 | 
			
		||||
                        w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                        w.set_stat_rx(Stat(stat_rx));
 | 
			
		||||
                        w.set_stat_tx(Stat(stat_tx));
 | 
			
		||||
                        w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                        w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            trace!("data_out WAITING, buf.len() = {}", buf.len());
 | 
			
		||||
    async fn setup<'a>(&'a mut self) -> [u8; 8] {
 | 
			
		||||
        loop {
 | 
			
		||||
            trace!("SETUP read waiting");
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if unsafe { regs.epr(0).read() }.stat_rx() == Stat::NAK {
 | 
			
		||||
                if EP0_SETUP.load(Ordering::Relaxed) {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
@@ -908,157 +812,209 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> {
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
            if EP0_SETUP.load(Ordering::Relaxed) {
 | 
			
		||||
                trace!("received another SETUP, aborting data_out.");
 | 
			
		||||
                return Err(EndpointError::Disabled);
 | 
			
		||||
            let mut buf = [0; 8];
 | 
			
		||||
            let rx_len = self.ep_out.read_data(&mut buf);
 | 
			
		||||
            if rx_len != Ok(8) {
 | 
			
		||||
                trace!("SETUP read failed: {:?}", rx_len);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let rx_len = self.ep_out.read_data(buf)?;
 | 
			
		||||
            EP0_SETUP.store(false, Ordering::Relaxed);
 | 
			
		||||
 | 
			
		||||
            trace!("SETUP read ok");
 | 
			
		||||
            return buf;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError> {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
        // When a SETUP is received, Stat/Stat is set to NAK.
 | 
			
		||||
        // On first transfer, we must set Stat=VALID, to get the OUT data stage.
 | 
			
		||||
        // We want Stat=STALL so that the host gets a STALL if it switches to the status
 | 
			
		||||
        // stage too soon, except in the last transfer we set Stat=NAK so that it waits
 | 
			
		||||
        // for the status stage, which we will ACK or STALL later.
 | 
			
		||||
        if first || last {
 | 
			
		||||
            let mut stat_rx = 0;
 | 
			
		||||
            let mut stat_tx = 0;
 | 
			
		||||
            if first {
 | 
			
		||||
                // change NAK -> VALID
 | 
			
		||||
                stat_rx ^= Stat::NAK.0 ^ Stat::VALID.0;
 | 
			
		||||
                stat_tx ^= Stat::NAK.0 ^ Stat::STALL.0;
 | 
			
		||||
            }
 | 
			
		||||
            if last {
 | 
			
		||||
                // change STALL -> VALID
 | 
			
		||||
                stat_tx ^= Stat::STALL.0 ^ Stat::NAK.0;
 | 
			
		||||
            }
 | 
			
		||||
            // Note: if this is the first AND last transfer, the above effectively
 | 
			
		||||
            // changes stat_tx like NAK -> NAK, so noop.
 | 
			
		||||
            unsafe {
 | 
			
		||||
                regs.epr(0).write(|w| {
 | 
			
		||||
                    w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                    w.set_stat_rx(Stat(match last {
 | 
			
		||||
                        // If last, set STAT_RX=STALL.
 | 
			
		||||
                        true => Stat::NAK.0 ^ Stat::STALL.0,
 | 
			
		||||
                        // Otherwise, set STAT_RX=VALID, to allow the host to send the next packet.
 | 
			
		||||
                        false => Stat::NAK.0 ^ Stat::VALID.0,
 | 
			
		||||
                    }));
 | 
			
		||||
                    w.set_stat_rx(Stat(stat_rx));
 | 
			
		||||
                    w.set_stat_tx(Stat(stat_tx));
 | 
			
		||||
                    w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                    w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                })
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            Ok(rx_len)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        trace!("data_out WAITING, buf.len() = {}", buf.len());
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            if unsafe { regs.epr(0).read() }.stat_rx() == Stat::NAK {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
        if EP0_SETUP.load(Ordering::Relaxed) {
 | 
			
		||||
            trace!("received another SETUP, aborting data_out.");
 | 
			
		||||
            return Err(EndpointError::Disabled);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let rx_len = self.ep_out.read_data(buf)?;
 | 
			
		||||
 | 
			
		||||
        unsafe {
 | 
			
		||||
            regs.epr(0).write(|w| {
 | 
			
		||||
                w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                w.set_stat_rx(Stat(match last {
 | 
			
		||||
                    // If last, set STAT_RX=STALL.
 | 
			
		||||
                    true => Stat::NAK.0 ^ Stat::STALL.0,
 | 
			
		||||
                    // Otherwise, set STAT_RX=VALID, to allow the host to send the next packet.
 | 
			
		||||
                    false => Stat::NAK.0 ^ Stat::VALID.0,
 | 
			
		||||
                }));
 | 
			
		||||
                w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                w.set_ctr_tx(true); // don't clear
 | 
			
		||||
            })
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        Ok(rx_len)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn data_in<'a>(&'a mut self, buf: &'a [u8], first: bool, last: bool) -> Self::DataInFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            trace!("control: data_in");
 | 
			
		||||
    async fn data_in(&mut self, data: &[u8], first: bool, last: bool) -> Result<(), EndpointError> {
 | 
			
		||||
        trace!("control: data_in");
 | 
			
		||||
 | 
			
		||||
            if buf.len() > self.ep_in.info.max_packet_size as usize {
 | 
			
		||||
                return Err(EndpointError::BufferOverflow);
 | 
			
		||||
        if data.len() > self.ep_in.info.max_packet_size as usize {
 | 
			
		||||
            return Err(EndpointError::BufferOverflow);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
        // When a SETUP is received, Stat is set to NAK.
 | 
			
		||||
        // We want it to be STALL in non-last transfers.
 | 
			
		||||
        // We want it to be VALID in last transfer, so the HW does the status stage.
 | 
			
		||||
        if first || last {
 | 
			
		||||
            let mut stat_rx = 0;
 | 
			
		||||
            if first {
 | 
			
		||||
                // change NAK -> STALL
 | 
			
		||||
                stat_rx ^= Stat::NAK.0 ^ Stat::STALL.0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
 | 
			
		||||
            // When a SETUP is received, Stat is set to NAK.
 | 
			
		||||
            // We want it to be STALL in non-last transfers.
 | 
			
		||||
            // We want it to be VALID in last transfer, so the HW does the status stage.
 | 
			
		||||
            if first || last {
 | 
			
		||||
                let mut stat_rx = 0;
 | 
			
		||||
                if first {
 | 
			
		||||
                    // change NAK -> STALL
 | 
			
		||||
                    stat_rx ^= Stat::NAK.0 ^ Stat::STALL.0;
 | 
			
		||||
                }
 | 
			
		||||
                if last {
 | 
			
		||||
                    // change STALL -> VALID
 | 
			
		||||
                    stat_rx ^= Stat::STALL.0 ^ Stat::VALID.0;
 | 
			
		||||
                }
 | 
			
		||||
                // Note: if this is the first AND last transfer, the above effectively
 | 
			
		||||
                // does a change of NAK -> VALID.
 | 
			
		||||
                unsafe {
 | 
			
		||||
                    regs.epr(0).write(|w| {
 | 
			
		||||
                        w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                        w.set_stat_rx(Stat(stat_rx));
 | 
			
		||||
                        w.set_ep_kind(last); // set OUT_STATUS if last.
 | 
			
		||||
                        w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                        w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
            if last {
 | 
			
		||||
                // change STALL -> VALID
 | 
			
		||||
                stat_rx ^= Stat::STALL.0 ^ Stat::VALID.0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            trace!("WRITE WAITING");
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
                EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
 | 
			
		||||
            if EP0_SETUP.load(Ordering::Relaxed) {
 | 
			
		||||
                trace!("received another SETUP, aborting data_in.");
 | 
			
		||||
                return Err(EndpointError::Disabled);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            self.ep_in.write_data(buf);
 | 
			
		||||
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            // Note: if this is the first AND last transfer, the above effectively
 | 
			
		||||
            // does a change of NAK -> VALID.
 | 
			
		||||
            unsafe {
 | 
			
		||||
                regs.epr(0).write(|w| {
 | 
			
		||||
                    w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                    w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0));
 | 
			
		||||
                    w.set_stat_rx(Stat(stat_rx));
 | 
			
		||||
                    w.set_ep_kind(last); // set OUT_STATUS if last.
 | 
			
		||||
                    w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                    w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                })
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            trace!("WRITE OK");
 | 
			
		||||
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            trace!("control: accept");
 | 
			
		||||
 | 
			
		||||
            self.ep_in.write_data(&[]);
 | 
			
		||||
 | 
			
		||||
            // Set OUT=stall, IN=accept
 | 
			
		||||
            unsafe {
 | 
			
		||||
                let epr = regs.epr(0).read();
 | 
			
		||||
                regs.epr(0).write(|w| {
 | 
			
		||||
                    w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                    w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0));
 | 
			
		||||
                    w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::VALID.0));
 | 
			
		||||
                    w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                    w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            trace!("control: accept WAITING");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            // Wait is needed, so that we don't set the address too soon, breaking the status stage.
 | 
			
		||||
            // (embassy-usb sets the address after accept() returns)
 | 
			
		||||
            poll_fn(|cx| {
 | 
			
		||||
                EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
                let regs = T::regs();
 | 
			
		||||
                if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK {
 | 
			
		||||
                    Poll::Ready(())
 | 
			
		||||
                } else {
 | 
			
		||||
                    Poll::Pending
 | 
			
		||||
                }
 | 
			
		||||
        trace!("WRITE WAITING");
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
            EP_OUT_WAKERS[0].register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
        if EP0_SETUP.load(Ordering::Relaxed) {
 | 
			
		||||
            trace!("received another SETUP, aborting data_in.");
 | 
			
		||||
            return Err(EndpointError::Disabled);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.ep_in.write_data(data);
 | 
			
		||||
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        unsafe {
 | 
			
		||||
            regs.epr(0).write(|w| {
 | 
			
		||||
                w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                w.set_stat_tx(Stat(Stat::NAK.0 ^ Stat::VALID.0));
 | 
			
		||||
                w.set_ep_kind(last); // set OUT_STATUS if last.
 | 
			
		||||
                w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                w.set_ctr_tx(true); // don't clear
 | 
			
		||||
            })
 | 
			
		||||
            .await;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
            trace!("control: accept OK");
 | 
			
		||||
        }
 | 
			
		||||
        trace!("WRITE OK");
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a> {
 | 
			
		||||
        async move {
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            trace!("control: reject");
 | 
			
		||||
    async fn accept(&mut self) {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        trace!("control: accept");
 | 
			
		||||
 | 
			
		||||
            // Set IN+OUT to stall
 | 
			
		||||
            unsafe {
 | 
			
		||||
                let epr = regs.epr(0).read();
 | 
			
		||||
                regs.epr(0).write(|w| {
 | 
			
		||||
                    w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                    w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0));
 | 
			
		||||
                    w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::STALL.0));
 | 
			
		||||
                    w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                    w.set_ctr_tx(true); // don't clear
 | 
			
		||||
                });
 | 
			
		||||
        self.ep_in.write_data(&[]);
 | 
			
		||||
 | 
			
		||||
        // Set OUT=stall, IN=accept
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let epr = regs.epr(0).read();
 | 
			
		||||
            regs.epr(0).write(|w| {
 | 
			
		||||
                w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0));
 | 
			
		||||
                w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::VALID.0));
 | 
			
		||||
                w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                w.set_ctr_tx(true); // don't clear
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        trace!("control: accept WAITING");
 | 
			
		||||
 | 
			
		||||
        // Wait is needed, so that we don't set the address too soon, breaking the status stage.
 | 
			
		||||
        // (embassy-usb sets the address after accept() returns)
 | 
			
		||||
        poll_fn(|cx| {
 | 
			
		||||
            EP_IN_WAKERS[0].register(cx.waker());
 | 
			
		||||
            let regs = T::regs();
 | 
			
		||||
            if unsafe { regs.epr(0).read() }.stat_tx() == Stat::NAK {
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            } else {
 | 
			
		||||
                Poll::Pending
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
        trace!("control: accept OK");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn reject(&mut self) {
 | 
			
		||||
        let regs = T::regs();
 | 
			
		||||
        trace!("control: reject");
 | 
			
		||||
 | 
			
		||||
        // Set IN+OUT to stall
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let epr = regs.epr(0).read();
 | 
			
		||||
            regs.epr(0).write(|w| {
 | 
			
		||||
                w.set_ep_type(EpType::CONTROL);
 | 
			
		||||
                w.set_stat_rx(Stat(epr.stat_rx().0 ^ Stat::STALL.0));
 | 
			
		||||
                w.set_stat_tx(Stat(epr.stat_tx().0 ^ Stat::STALL.0));
 | 
			
		||||
                w.set_ctr_rx(true); // don't clear
 | 
			
		||||
                w.set_ctr_tx(true); // don't clear
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ atomic-polyfill = "1.0.1"
 | 
			
		||||
critical-section = "1.1"
 | 
			
		||||
heapless = "0.7.5"
 | 
			
		||||
cfg-if = "1.0.0"
 | 
			
		||||
embedded-io = "0.3.1"
 | 
			
		||||
embedded-io = "0.4.0"
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
futures-executor = { version = "0.3.17", features = [ "thread-pool" ] }
 | 
			
		||||
 
 | 
			
		||||
@@ -134,7 +134,7 @@ log = { version = "0.4.14", optional = true }
 | 
			
		||||
 | 
			
		||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9", optional = true}
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3", optional = true}
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true}
 | 
			
		||||
 | 
			
		||||
futures-util = { version = "0.3.17", default-features = false }
 | 
			
		||||
embassy-sync = { version = "0.1", path = "../embassy-sync" }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#![no_std]
 | 
			
		||||
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
#![feature(async_fn_in_trait)]
 | 
			
		||||
#![allow(incomplete_features)]
 | 
			
		||||
 | 
			
		||||
/// Direction of USB traffic. Note that in the USB standard the direction is always indicated from
 | 
			
		||||
/// the perspective of the host, which is backward for devices, but the standard directions are used
 | 
			
		||||
@@ -155,27 +155,14 @@ pub trait Driver<'a> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait Bus {
 | 
			
		||||
    type EnableFuture<'a>: Future<Output = ()> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    type DisableFuture<'a>: Future<Output = ()> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    type PollFuture<'a>: Future<Output = Event> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    type RemoteWakeupFuture<'a>: Future<Output = Result<(), Unsupported>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    /// Enables the USB peripheral. Soon after enabling the device will be reset, so
 | 
			
		||||
    /// there is no need to perform a USB reset in this method.
 | 
			
		||||
    fn enable(&mut self) -> Self::EnableFuture<'_>;
 | 
			
		||||
    async fn enable(&mut self);
 | 
			
		||||
 | 
			
		||||
    /// Disables and powers down the USB peripheral.
 | 
			
		||||
    fn disable(&mut self) -> Self::DisableFuture<'_>;
 | 
			
		||||
    async fn disable(&mut self);
 | 
			
		||||
 | 
			
		||||
    fn poll<'a>(&'a mut self) -> Self::PollFuture<'a>;
 | 
			
		||||
    async fn poll(&mut self) -> Event;
 | 
			
		||||
 | 
			
		||||
    /// Sets the device USB address to `addr`.
 | 
			
		||||
    fn set_address(&mut self, addr: u8);
 | 
			
		||||
@@ -209,85 +196,57 @@ pub trait Bus {
 | 
			
		||||
    ///
 | 
			
		||||
    /// * [`Unsupported`](crate::driver::Unsupported) - This UsbBus implementation doesn't support
 | 
			
		||||
    ///   remote wakeup or it has not been enabled at creation time.
 | 
			
		||||
    fn remote_wakeup(&mut self) -> Self::RemoteWakeupFuture<'_>;
 | 
			
		||||
    async fn remote_wakeup(&mut self) -> Result<(), Unsupported>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait Endpoint {
 | 
			
		||||
    type WaitEnabledFuture<'a>: Future<Output = ()> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    /// Get the endpoint address
 | 
			
		||||
    fn info(&self) -> &EndpointInfo;
 | 
			
		||||
 | 
			
		||||
    /// Waits for the endpoint to be enabled.
 | 
			
		||||
    fn wait_enabled(&mut self) -> Self::WaitEnabledFuture<'_>;
 | 
			
		||||
    async fn wait_enabled(&mut self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait EndpointOut: Endpoint {
 | 
			
		||||
    type ReadFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    /// Reads a single packet of data from the endpoint, and returns the actual length of
 | 
			
		||||
    /// the packet.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This should also clear any NAK flags and prepare the endpoint to receive the next packet.
 | 
			
		||||
    fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a>;
 | 
			
		||||
    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait ControlPipe {
 | 
			
		||||
    type SetupFuture<'a>: Future<Output = [u8; 8]> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    type DataOutFuture<'a>: Future<Output = Result<usize, EndpointError>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    type DataInFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    type AcceptFuture<'a>: Future<Output = ()> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
    type RejectFuture<'a>: Future<Output = ()> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    /// Maximum packet size for the control pipe
 | 
			
		||||
    fn max_packet_size(&self) -> usize;
 | 
			
		||||
 | 
			
		||||
    /// Reads a single setup packet from the endpoint.
 | 
			
		||||
    fn setup<'a>(&'a mut self) -> Self::SetupFuture<'a>;
 | 
			
		||||
    async fn setup<'a>(&'a mut self) -> [u8; 8];
 | 
			
		||||
 | 
			
		||||
    /// Reads a DATA OUT packet into `buf` in response to a control write request.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Must be called after `setup()` for requests with `direction` of `Out`
 | 
			
		||||
    /// and `length` greater than zero.
 | 
			
		||||
    fn data_out<'a>(&'a mut self, buf: &'a mut [u8], first: bool, last: bool) -> Self::DataOutFuture<'a>;
 | 
			
		||||
    async fn data_out(&mut self, buf: &mut [u8], first: bool, last: bool) -> Result<usize, EndpointError>;
 | 
			
		||||
 | 
			
		||||
    /// Sends a DATA IN packet with `data` in response to a control read request.
 | 
			
		||||
    ///
 | 
			
		||||
    /// If `last_packet` is true, the STATUS packet will be ACKed following the transfer of `data`.
 | 
			
		||||
    fn data_in<'a>(&'a mut self, data: &'a [u8], first: bool, last: bool) -> Self::DataInFuture<'a>;
 | 
			
		||||
    async fn data_in(&mut self, data: &[u8], first: bool, last: bool) -> Result<(), EndpointError>;
 | 
			
		||||
 | 
			
		||||
    /// Accepts a control request.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Causes the STATUS packet for the current request to be ACKed.
 | 
			
		||||
    fn accept<'a>(&'a mut self) -> Self::AcceptFuture<'a>;
 | 
			
		||||
    async fn accept(&mut self);
 | 
			
		||||
 | 
			
		||||
    /// Rejects a control request.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Sets a STALL condition on the pipe to indicate an error.
 | 
			
		||||
    fn reject<'a>(&'a mut self) -> Self::RejectFuture<'a>;
 | 
			
		||||
    async fn reject(&mut self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait EndpointIn: Endpoint {
 | 
			
		||||
    type WriteFuture<'a>: Future<Output = Result<(), EndpointError>> + 'a
 | 
			
		||||
    where
 | 
			
		||||
        Self: 'a;
 | 
			
		||||
 | 
			
		||||
    /// Writes a single packet of data to the endpoint.
 | 
			
		||||
    fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a>;
 | 
			
		||||
    async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["de
 | 
			
		||||
embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
 | 
			
		||||
embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"], optional = true }
 | 
			
		||||
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"], optional = true }
 | 
			
		||||
embedded-io = "0.3.1"
 | 
			
		||||
embedded-io = "0.4.0"
 | 
			
		||||
embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx126x", "time", "defmt"], optional = true }
 | 
			
		||||
 | 
			
		||||
lorawan-device = { version = "0.8.0", default-features = false, features = ["async"], optional = true }
 | 
			
		||||
@@ -34,4 +34,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
 | 
			
		||||
rand = { version = "0.8.4", default-features = false }
 | 
			
		||||
embedded-storage = "0.3.0"
 | 
			
		||||
usbd-hid = "0.6.0"
 | 
			
		||||
serde = { version = "1.0.136", default-features = false }
 | 
			
		||||
serde = { version = "1.0.136", default-features = false }
 | 
			
		||||
@@ -29,8 +29,8 @@ display-interface = "0.4.1"
 | 
			
		||||
byte-slice-cast = { version = "1.2.0", default-features = false }
 | 
			
		||||
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
 | 
			
		||||
embedded-hal-async = { version = "0.1.0-alpha.3" }
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async", "defmt"] }
 | 
			
		||||
embedded-hal-async = "0.2.0-alpha.0"
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async", "defmt"] }
 | 
			
		||||
embedded-storage = { version = "0.3" }
 | 
			
		||||
static_cell = "1.0.0"
 | 
			
		||||
log = "0.4"
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["lo
 | 
			
		||||
embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] }
 | 
			
		||||
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] }
 | 
			
		||||
embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "tcp", "udp", "dhcpv4", "pool-16"] }
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async", "std", "futures"] }
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async", "std", "futures"] }
 | 
			
		||||
critical-section = { version = "1.1", features = ["std"] }
 | 
			
		||||
 | 
			
		||||
async-io = "1.6.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ defmt-rtt = "0.3"
 | 
			
		||||
cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
 | 
			
		||||
cortex-m-rt = "0.7.0"
 | 
			
		||||
embedded-hal = "0.2.6"
 | 
			
		||||
embedded-io = "0.3.1"
 | 
			
		||||
embedded-io = "0.4.0"
 | 
			
		||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
 | 
			
		||||
heapless = { version = "0.7.5", default-features = false }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ embassy-executor = { version = "0.1.0", path = "../../embassy-executor", feature
 | 
			
		||||
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
 | 
			
		||||
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "net", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"]  }
 | 
			
		||||
embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] }
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async"] }
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async"] }
 | 
			
		||||
 | 
			
		||||
defmt = "0.3"
 | 
			
		||||
defmt-rtt = "0.3"
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ embassy-executor = { version = "0.1.0", path = "../../embassy-executor", feature
 | 
			
		||||
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
 | 
			
		||||
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
 | 
			
		||||
embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "pool-16", "unstable-traits"] }
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async"] }
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async"] }
 | 
			
		||||
 | 
			
		||||
defmt = "0.3"
 | 
			
		||||
defmt-rtt = "0.3"
 | 
			
		||||
@@ -19,8 +19,8 @@ cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
 | 
			
		||||
cortex-m-rt = "0.7.0"
 | 
			
		||||
embedded-hal = "0.2.6"
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3" }
 | 
			
		||||
embedded-nal-async = "0.2.0"
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0" }
 | 
			
		||||
embedded-nal-async = { git = "https://github.com/embassy-rs/embedded-nal.git", rev = "691601e550449a53ab3a7c5eaa0411aee0a64ed0" }
 | 
			
		||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
 | 
			
		||||
heapless = { version = "0.7.5", default-features = false }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ defmt = "0.3"
 | 
			
		||||
defmt-rtt = "0.3"
 | 
			
		||||
 | 
			
		||||
embedded-storage = "0.3.0"
 | 
			
		||||
embedded-io = "0.3.1"
 | 
			
		||||
embedded-io = "0.4.0"
 | 
			
		||||
 | 
			
		||||
cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
 | 
			
		||||
cortex-m-rt = "0.7.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
 | 
			
		||||
cortex-m-rt = "0.7.0"
 | 
			
		||||
embedded-hal = "0.2.6"
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3" }
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0" }
 | 
			
		||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
 | 
			
		||||
heapless = { version = "0.7.5", default-features = false }
 | 
			
		||||
 
 | 
			
		||||
@@ -26,5 +26,5 @@ embedded-hal = "0.2.6"
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
 | 
			
		||||
heapless = { version = "0.7.5", default-features = false }
 | 
			
		||||
rand_core = { version = "0.6.3", default-features = false }
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async"] }
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async"] }
 | 
			
		||||
static_cell = "1.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -21,8 +21,3 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
 | 
			
		||||
heapless = { version = "0.7.5", default-features = false }
 | 
			
		||||
 | 
			
		||||
micromath = "2.0.0"
 | 
			
		||||
 | 
			
		||||
#[patch.crates-io]
 | 
			
		||||
#defmt = { git="https://github.com/knurling-rs/defmt.git" }
 | 
			
		||||
#defmt-rtt = { git="https://github.com/knurling-rs/defmt.git" }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
# Before upgrading check that everything is available on all tier1 targets here:
 | 
			
		||||
# https://rust-lang.github.io/rustup-components-history
 | 
			
		||||
[toolchain]
 | 
			
		||||
channel = "nightly-2022-10-25"
 | 
			
		||||
channel = "nightly-2022-11-22"
 | 
			
		||||
components = [ "rust-src", "rustfmt" ]
 | 
			
		||||
targets = [
 | 
			
		||||
    "thumbv7em-none-eabi",
 | 
			
		||||
 
 | 
			
		||||
@@ -18,10 +18,10 @@ cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
 | 
			
		||||
cortex-m-rt = "0.7.0"
 | 
			
		||||
embedded-hal = "0.2.6"
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3" }
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0" }
 | 
			
		||||
panic-probe = { version = "0.3.0", features = ["print-defmt"] }
 | 
			
		||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
 | 
			
		||||
embedded-io = { version = "0.3.1", features = ["async"] }
 | 
			
		||||
embedded-io = { version = "0.4.0", features = ["async"] }
 | 
			
		||||
embedded-storage = { version = "0.3" }
 | 
			
		||||
 | 
			
		||||
[profile.dev]
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
 | 
			
		||||
cortex-m-rt = "0.7.0"
 | 
			
		||||
embedded-hal = "0.2.6"
 | 
			
		||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" }
 | 
			
		||||
embedded-hal-async = { version = "=0.1.0-alpha.3" }
 | 
			
		||||
embedded-hal-async = { version = "=0.2.0-alpha.0" }
 | 
			
		||||
panic-probe = { version = "0.3.0", features = ["print-defmt"] }
 | 
			
		||||
 | 
			
		||||
[profile.dev]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user