summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2022-05-04 20:48:37 +0200
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2022-05-07 01:45:54 +0200
commit931a137f8c5a760c2e06c437c98d14eff3e3a587 (patch)
tree7b79ba8397c3eff730f634cbaf77aa5571337191
parentfc32b3750c448a81b7dd44cf9de98723b8eb4fcf (diff)
downloadembassy-931a137f8c5a760c2e06c437c98d14eff3e3a587.zip
Replace embassy::io with embedded_io.
-rw-r--r--embassy-net/Cargo.toml3
-rw-r--r--embassy-net/src/device.rs9
-rw-r--r--embassy-net/src/lib.rs9
-rw-r--r--embassy-net/src/tcp/io_impl.rs67
-rw-r--r--embassy-net/src/tcp/mod.rs (renamed from embassy-net/src/tcp_socket.rs)131
-rw-r--r--embassy-nrf/Cargo.toml5
-rw-r--r--embassy-nrf/src/buffered_uarte.rs144
-rw-r--r--embassy-nrf/src/lib.rs1
-rw-r--r--embassy-stm32/Cargo.toml8
-rw-r--r--embassy-stm32/build.rs377
-rw-r--r--embassy-stm32/src/eth/mod.rs2
-rw-r--r--embassy-stm32/src/lib.rs2
-rw-r--r--embassy-stm32/src/usart/buffered.rs238
-rw-r--r--embassy-stm32/src/usart/mod.rs225
-rw-r--r--embassy/src/io/error.rs142
-rw-r--r--embassy/src/io/mod.rs11
-rw-r--r--embassy/src/io/std.rs41
-rw-r--r--embassy/src/io/traits.rs175
-rw-r--r--embassy/src/io/util/copy_buf.rs80
-rw-r--r--embassy/src/io/util/drain.rs41
-rw-r--r--embassy/src/io/util/flush.rs32
-rw-r--r--embassy/src/io/util/mod.rs177
-rw-r--r--embassy/src/io/util/read.rs39
-rw-r--r--embassy/src/io/util/read_buf.rs34
-rw-r--r--embassy/src/io/util/read_byte.rs36
-rw-r--r--embassy/src/io/util/read_exact.rs48
-rw-r--r--embassy/src/io/util/read_to_end.rs48
-rw-r--r--embassy/src/io/util/read_while.rs61
-rw-r--r--embassy/src/io/util/skip_while.rs45
-rw-r--r--embassy/src/io/util/split.rs43
-rw-r--r--embassy/src/io/util/write.rs33
-rw-r--r--embassy/src/io/util/write_all.rs44
-rw-r--r--embassy/src/io/util/write_byte.rs39
-rw-r--r--embassy/src/lib.rs1
-rw-r--r--examples/nrf/Cargo.toml3
-rw-r--r--examples/nrf/src/bin/buffered_uart.rs2
-rw-r--r--examples/nrf/src/bin/usb_ethernet.rs8
-rw-r--r--examples/std/Cargo.toml3
-rw-r--r--examples/std/src/bin/net.rs5
-rw-r--r--examples/std/src/bin/serial.rs14
-rw-r--r--examples/stm32f7/Cargo.toml1
-rw-r--r--examples/stm32f7/src/bin/eth.rs7
-rw-r--r--examples/stm32h7/Cargo.toml3
-rw-r--r--examples/stm32h7/src/bin/eth.rs7
-rw-r--r--examples/stm32l0/.cargo/config.toml2
-rw-r--r--examples/stm32l0/Cargo.toml4
-rw-r--r--examples/stm32l0/src/bin/usart_irq.rs11
47 files changed, 699 insertions, 1762 deletions
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml
index 2d0116bd..1b2847a0 100644
--- a/embassy-net/Cargo.toml
+++ b/embassy-net/Cargo.toml
@@ -31,12 +31,15 @@ pool-32 = []
pool-64 = []
pool-128 = []
+nightly = ["embedded-io/async"]
+
[dependencies]
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy = { version = "0.1.0", path = "../embassy" }
+embedded-io = "0.2.0"
managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
heapless = { version = "0.7.5", default-features = false }
diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs
index f66ebc19..1f4fa520 100644
--- a/embassy-net/src/device.rs
+++ b/embassy-net/src/device.rs
@@ -4,7 +4,6 @@ use smoltcp::phy::DeviceCapabilities;
use smoltcp::time::Instant as SmolInstant;
use crate::packet_pool::PacketBoxExt;
-use crate::Result;
use crate::{Packet, PacketBox, PacketBuf};
#[derive(PartialEq, Eq, Clone, Copy)]
@@ -78,9 +77,9 @@ pub struct RxToken {
}
impl smoltcp::phy::RxToken for RxToken {
- fn consume<R, F>(mut self, _timestamp: SmolInstant, f: F) -> Result<R>
+ fn consume<R, F>(mut self, _timestamp: SmolInstant, f: F) -> smoltcp::Result<R>
where
- F: FnOnce(&mut [u8]) -> Result<R>,
+ F: FnOnce(&mut [u8]) -> smoltcp::Result<R>,
{
f(&mut self.pkt)
}
@@ -92,9 +91,9 @@ pub struct TxToken<'a> {
}
impl<'a> smoltcp::phy::TxToken for TxToken<'a> {
- fn consume<R, F>(self, _timestamp: SmolInstant, len: usize, f: F) -> Result<R>
+ fn consume<R, F>(self, _timestamp: SmolInstant, len: usize, f: F) -> smoltcp::Result<R>
where
- F: FnOnce(&mut [u8]) -> Result<R>,
+ F: FnOnce(&mut [u8]) -> smoltcp::Result<R>,
{
let mut buf = self.pkt.slice(0..len);
let r = f(&mut buf)?;
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index ffe786b3..ded84190 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -1,5 +1,9 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::new_without_default)]
+#![cfg_attr(
+ feature = "nightly",
+ feature(generic_associated_types, type_alias_impl_trait)
+)]
// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;
@@ -20,9 +24,7 @@ pub use stack::{
};
#[cfg(feature = "tcp")]
-mod tcp_socket;
-#[cfg(feature = "tcp")]
-pub use tcp_socket::TcpSocket;
+pub mod tcp;
// smoltcp reexports
pub use smoltcp::phy::{DeviceCapabilities, Medium};
@@ -32,4 +34,3 @@ pub use smoltcp::time::Instant as SmolInstant;
pub use smoltcp::wire::{EthernetAddress, HardwareAddress};
pub use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address, Ipv4Cidr};
pub type Interface = smoltcp::iface::Interface<'static, device::DeviceAdapter>;
-pub use smoltcp::{Error, Result};
diff --git a/embassy-net/src/tcp/io_impl.rs b/embassy-net/src/tcp/io_impl.rs
new file mode 100644
index 00000000..15573349
--- /dev/null
+++ b/embassy-net/src/tcp/io_impl.rs
@@ -0,0 +1,67 @@
+use core::future::Future;
+use core::task::Poll;
+use futures::future::poll_fn;
+
+use super::{Error, TcpSocket};
+
+impl<'d> embedded_io::asynch::Read for TcpSocket<'d> {
+ type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
+ where
+ Self: 'a;
+
+ fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
+ poll_fn(move |cx| {
+ // CAUTION: smoltcp semantics around EOF are different to what you'd expect
+ // from posix-like IO, so we have to tweak things here.
+ self.with(|s, _| match s.recv_slice(buf) {
+ // No data ready
+ Ok(0) => {
+ s.register_recv_waker(cx.waker());
+ Poll::Pending
+ }
+ // Data ready!
+ Ok(n) => Poll::Ready(Ok(n)),
+ // EOF
+ Err(smoltcp::Error::Finished) => Poll::Ready(Ok(0)),
+ // Connection reset. TODO: this can also be timeouts etc, investigate.
+ Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
+ // smoltcp returns no errors other than the above.
+ Err(_) => unreachable!(),
+ })
+ })
+ }
+}
+
+impl<'d> embedded_io::asynch::Write for TcpSocket<'d> {
+ type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
+ where
+ Self: 'a;
+
+ fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
+ poll_fn(move |cx| {
+ self.with(|s, _| match s.send_slice(buf) {
+ // Not ready to send (no space in the tx buffer)
+ Ok(0) => {
+ s.register_send_waker(cx.waker());
+ Poll::Pending
+ }
+ // Some data sent
+ Ok(n) => Poll::Ready(Ok(n)),
+ // Connection reset. TODO: this can also be timeouts etc, investigate.
+ Err(smoltcp::Error::Illegal) => Poll::Ready(Err(Error::ConnectionReset)),
+ // smoltcp returns no errors other than the above.
+ Err(_) => unreachable!(),
+ })
+ })
+ }
+
+ type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
+ where
+ Self: 'a;
+
+ fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
+ poll_fn(move |_| {
+ Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
+ })
+ }
+}
diff --git a/embassy-net/src/tcp_socket.rs b/embassy-net/src/tcp/mod.rs
index 5637505d..3bfd4c7b 100644
--- a/embassy-net/src/tcp_socket.rs
+++ b/embassy-net/src/tcp/mod.rs
@@ -1,17 +1,46 @@
use core::marker::PhantomData;
use core::mem;
-use core::pin::Pin;
-use core::task::{Context, Poll};
-use embassy::io;
-use embassy::io::{AsyncBufRead, AsyncWrite};
+use core::task::Poll;
use smoltcp::iface::{Context as SmolContext, SocketHandle};
use smoltcp::socket::TcpSocket as SyncTcpSocket;
use smoltcp::socket::{TcpSocketBuffer, TcpState};
use smoltcp::time::Duration;
use smoltcp::wire::IpEndpoint;
+#[cfg(feature = "nightly")]
+mod io_impl;
+
use super::stack::Stack;
-use crate::{Error, Result};
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum Error {
+ ConnectionReset,
+}
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum ConnectError {
+ /// The socket is already connected or listening.
+ InvalidState,
+ /// The remote host rejected the connection with a RST packet.
+ ConnectionReset,
+ /// Connect timed out.
+ TimedOut,
+ /// No route to host.
+ NoRoute,
+}
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[cfg_attr(feature = "defmt", derive(defmt::Format))]
+pub enum AcceptError {
+ /// The socket is already connected or listening.
+ InvalidState,
+ /// Invalid listen port
+ InvalidPort,
+ /// The remote host rejected the connection with a RST packet.
+ ConnectionReset,
+}
pub struct TcpSocket<'a> {
handle: SocketHandle,
@@ -37,17 +66,25 @@ impl<'a> TcpSocket<'a> {
}
}
- pub async fn connect<T>(&mut self, remote_endpoint: T) -> Result<()>
+ pub async fn connect<T>(&mut self, remote_endpoint: T) -> Result<(), ConnectError>
where
T: Into<IpEndpoint>,
{
let local_port = Stack::with(|stack| stack.get_local_port());
- self.with(|s, cx| s.connect(cx, remote_endpoint, local_port))?;
+ match self.with(|s, cx| s.connect(cx, remote_endpoint, local_port)) {
+ Ok(()) => {}
+ Err(smoltcp::Error::Illegal) => return Err(ConnectError::InvalidState),
+ Err(smoltcp::Error::Unaddressable) => return Err(ConnectError::NoRoute),
+ // smoltcp returns no errors other than the above.
+ Err(_) => unreachable!(),
+ }
futures::future::poll_fn(|cx| {
self.with(|s, _| match s.state() {
- TcpState::Closed | TcpState::TimeWait => Poll::Ready(Err(Error::Unaddressable)),
- TcpState::Listen => Poll::Ready(Err(Error::Illegal)),
+ TcpState::Closed | TcpState::TimeWait => {
+ Poll::Ready(Err(ConnectError::ConnectionReset))
+ }
+ TcpState::Listen => unreachable!(),
TcpState::SynSent | TcpState::SynReceived => {
s.register_send_waker(cx.waker());
Poll::Pending
@@ -58,11 +95,17 @@ impl<'a> TcpSocket<'a> {
.await
}
- pub async fn accept<T>(&mut self, local_endpoint: T) -> Result<()>
+ pub async fn accept<T>(&mut self, local_endpoint: T) -> Result<(), AcceptError>
where
T: Into<IpEndpoint>,
{
- self.with(|s, _| s.listen(local_endpoint))?;
+ match self.with(|s, _| s.listen(local_endpoint)) {
+ Ok(()) => {}
+ Err(smoltcp::Error::Illegal) => return Err(AcceptError::InvalidState),
+ Err(smoltcp::Error::Unaddressable) => return Err(AcceptError::InvalidPort),
+ // smoltcp returns no errors other than the above.
+ Err(_) => unreachable!(),
+ }
futures::future::poll_fn(|cx| {
self.with(|s, _| match s.state() {
@@ -130,11 +173,6 @@ impl<'a> TcpSocket<'a> {
}
}
-fn to_ioerr(_err: Error) -> io::Error {
- // todo
- io::Error::Other
-}
-
impl<'a> Drop for TcpSocket<'a> {
fn drop(&mut self) {
Stack::with(|stack| {
@@ -143,63 +181,12 @@ impl<'a> Drop for TcpSocket<'a> {
}
}
-impl<'a> AsyncBufRead for TcpSocket<'a> {
- fn poll_fill_buf<'z>(
- self: Pin<&'z mut Self>,
- cx: &mut Context<'_>,
- ) -> Poll<io::Result<&'z [u8]>> {
- self.with(|s, _| match s.peek(1 << 30) {
- // No data ready
- Ok(buf) if buf.is_empty() => {
- s.register_recv_waker(cx.waker());
- Poll::Pending
- }
- // Data ready!
- Ok(buf) => {
- // Safety:
- // - User can't touch the inner TcpSocket directly at all.
- // - The socket itself won't touch these bytes until consume() is called, which
- // requires the user to release this borrow.
- let buf: &'z [u8] = unsafe { core::mem::transmute(&*buf) };
- Poll::Ready(Ok(buf))
- }
- // EOF
- Err(Error::Finished) => Poll::Ready(Ok(&[][..])),
- // Error
- Err(e) => Poll::Ready(Err(to_ioerr(e))),
- })
- }
-
- fn consume(self: Pin<&mut Self>, amt: usize) {
- if amt == 0 {
- // smoltcp's recv returns Finished if we're at EOF,
- // even if we're "reading" 0 bytes.
- return;
- }
- self.with(|s, _| s.recv(|_| (amt, ()))).unwrap()
+impl embedded_io::Error for Error {
+ fn kind(&self) -> embedded_io::ErrorKind {
+ embedded_io::ErrorKind::Other
}
}
-impl<'a> AsyncWrite for TcpSocket<'a> {
- fn poll_write(
- self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<io::Result<usize>> {
- self.with(|s, _| match s.send_slice(buf) {
- // Not ready to send (no space in the tx buffer)
- Ok(0) => {
- s.register_send_waker(cx.waker());
- Poll::Pending
- }
- // Some data sent
- Ok(n) => Poll::Ready(Ok(n)),
- // Error
- Err(e) => Poll::Ready(Err(to_ioerr(e))),
- })
- }
-
- fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
- Poll::Ready(Ok(())) // TODO: Is there a better implementation for this?
- }
+impl<'d> embedded_io::Io for TcpSocket<'d> {
+ type Error = Error;
}
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index b7c09286..cf61abcc 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -19,10 +19,10 @@ flavors = [
time = ["embassy/time"]
-defmt = ["dep:defmt", "embassy/defmt", "embassy-usb?/defmt"]
+defmt = ["dep:defmt", "embassy/defmt", "embassy-usb?/defmt", "embedded-io?/defmt"]
# Enable nightly-only features
-nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async"]
+nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async", "dep:embedded-io"]
# Reexport the PAC for the currently enabled chip at `embassy_nrf::pac`.
# This is unstable because semver-minor (non-breaking) releases of embassy-nrf may major-bump (breaking) the PAC version.
@@ -73,6 +73,7 @@ embassy-usb = {version = "0.1.0", path = "../embassy-usb", optional=true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8", optional = true}
embedded-hal-async = { version = "0.1.0-alpha.0", optional = true}
+embedded-io = { version = "0.2.0", features = ["async"], optional = true }
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index b49c1278..fc4e9c8d 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -14,18 +14,17 @@
//! Please also see [crate::uarte] to understand when [BufferedUarte] should be used.
use core::cmp::min;
+use core::future::Future;
use core::marker::PhantomData;
-use core::mem;
-use core::pin::Pin;
use core::sync::atomic::{compiler_fence, Ordering};
-use core::task::{Context, Poll};
+use core::task::Poll;
use embassy::interrupt::InterruptExt;
-use embassy::io::{AsyncBufRead, AsyncWrite};
use embassy::util::Unborrow;
use embassy::waitqueue::WakerRegistration;
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_hal_common::ring_buffer::RingBuffer;
use embassy_hal_common::{low_power_wait_until, unborrow};
+use futures::future::poll_fn;
use crate::gpio::Pin as GpioPin;
use crate::pac;
@@ -197,82 +196,99 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
}
}
-impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> {
- fn poll_fill_buf(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- ) -> Poll<embassy::io::Result<&[u8]>> {
- self.inner.with(|state| {
- compiler_fence(Ordering::SeqCst);
- trace!("poll_read");
-
- // We have data ready in buffer? Return it.
- let buf = state.rx.pop_buf();
- if !buf.is_empty() {
- trace!(" got {:?} {:?}", buf.as_ptr() as u32, buf.len());
- let buf: &[u8] = buf;
- let buf: &[u8] = unsafe { mem::transmute(buf) };
- return Poll::Ready(Ok(buf));
+impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUarte<'d, U, T> {
+ type Error = core::convert::Infallible;
+}
+
+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>>
+ where
+ Self: 'a;
+
+ fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
+ poll_fn(move |cx| {
+ let mut do_pend = false;
+ let res = self.inner.with(|state| {
+ compiler_fence(Ordering::SeqCst);
+ trace!("poll_read");
+
+ // We have data ready in buffer? Return it.
+ let data = state.rx.pop_buf();
+ if !data.is_empty() {
+ trace!(" got {:?} {:?}", data.as_ptr() as u32, data.len());
+ let len = data.len().min(data.len());
+ buf[..len].copy_from_slice(&data[..len]);
+ state.rx.pop(len);
+ do_pend = true;
+ return Poll::Ready(Ok(len));
+ }
+
+ trace!(" empty");
+ state.rx_waker.register(cx.waker());
+ Poll::Pending
+ });
+ if do_pend {
+ self.inner.pend();
}
- trace!(" empty");
- state.rx_waker.register(cx.waker());
- Poll::<embassy::io::Result<&[u8]>>::Pending
+ res
})
}
-
- fn consume(mut self: Pin<&mut Self>, amt: usize) {
- self.inner.with(|state| {
- trace!("consume {:?}", amt);
- state.rx.pop(amt);
- });
- self.inner.pend();
- }
}
-impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, T> {
- fn poll_write(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<embassy::io::Result<usize>> {
- let poll = self.inner.with(|state| {
- trace!("poll_write: {:?}", buf.len());
-
- let tx_buf = state.tx.push_buf();
- if tx_buf.is_empty() {
- trace!("poll_write: pending");
- state.tx_waker.register(cx.waker());
- return Poll::Pending;
- }
+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>>
+ where
+ Self: 'a;
+
+ fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
+ poll_fn(move |cx| {
+ let res = self.inner.with(|state| {
+ trace!("poll_write: {:?}", buf.len());
+
+ let tx_buf = state.tx.push_buf();
+ if tx_buf.is_empty() {
+ trace!("poll_write: pending");
+ state.tx_waker.register(cx.waker());
+ return Poll::Pending;
+ }
- let n = min(tx_buf.len(), buf.len());
- tx_buf[..n].copy_from_slice(&buf[..n]);
- state.tx.push(n);
+ let n = min(tx_buf.len(), buf.len());
+ tx_buf[..n].copy_from_slice(&buf[..n]);
+ state.tx.push(n);
- trace!("poll_write: queued {:?}", n);
+ trace!("poll_write: queued {:?}", n);
- compiler_fence(Ordering::SeqCst);
+ compiler_fence(Ordering::SeqCst);
- Poll::Ready(Ok(n))
- });
+ Poll::Ready(Ok(n))
+ });
- self.inner.pend();
+ self.inner.pend();
- poll
+ res
+ })
}
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<embassy::io::Result<()>> {
- self.inner.with(|state| {
- trace!("poll_flush");
+ type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
+ where
+ Self: 'a;
- if !state.tx.is_empty() {
- trace!("poll_flush: pending");
- state.tx_waker.register(cx.waker());
- return Poll::Pending;
- }
+ fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
+ poll_fn(move |cx| {
+ self.inner.with(|state| {
+ trace!("poll_flush");
+
+ if !state.tx.is_empty() {
+ trace!("poll_flush: pending");
+ state.tx_waker.register(cx.waker());
+ return Poll::Pending;
+ }
- Poll::Ready(Ok(()))
+ Poll::Ready(Ok(()))
+ })
})
}
}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 3b180902..865f33d7 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -64,6 +64,7 @@ pub(crate) mod util;
#[cfg(feature = "_time-driver")]
mod time_driver;
+#[cfg(feature = "nightly")]
pub mod buffered_uarte;
pub mod gpio;
#[cfg(feature = "gpiote")]
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index ea9ac3b5..9686e016 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -57,12 +57,13 @@ critical-section = "0.2.5"
bare-metal = "1.0.0"
atomic-polyfill = "0.1.5"
stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", features = ["rt"] }
-vcell = { version = "0.1.3", optional = true }
+vcell = "0.1.3"
bxcan = "0.6.2"
nb = "1.0.0"
stm32-fmc = "0.2.4"
seq-macro = "0.2.2"
cfg-if = "1.0.0"
+embedded-io = { version = "0.2.0", features = ["async"], optional = true }
[build-dependencies]
proc-macro2 = "1.0.36"
@@ -70,8 +71,9 @@ quote = "1.0.15"
stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false, features = ["metadata"]}
[features]
+defmt = ["dep:defmt", "embassy/defmt", "embedded-io?/defmt" ]
sdmmc-rs = ["embedded-sdmmc"]
-net = ["embassy-net", "vcell"]
+net = ["embassy-net" ]
memory-x = ["stm32-metapac/memory-x"]
subghz = []
exti = []
@@ -88,7 +90,7 @@ time-driver-tim12 = ["_time-driver"]
time-driver-tim15 = ["_time-driver"]
# Enable nightly-only features
-nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embedded-storage-async"]
+nightly = ["embassy/nightly", "embassy-net?/nightly", "embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io"]
# Reexport stm32-metapac at `embassy_stm32::pac`.
# This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index db757764..490f2d8f 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -244,200 +244,200 @@ fn main() {
#[rustfmt::skip]
let signals: HashMap<_, _> = [
- // (kind, signal) => (trait, cfgs)
- (("usart", "TX"), (quote!(crate::usart::TxPin), quote!())),
- (("usart", "RX"), (quote!(crate::usart::RxPin), quote!())),
- (("usart", "CTS"), (quote!(crate::usart::CtsPin), quote!())),
- (("usart", "RTS"), (quote!(crate::usart::RtsPin), quote!())),
- (("usart", "CK"), (quote!(crate::usart::CkPin), quote!())),
- (("usart", "TX"), (quote!(crate::usart::TxPin), quote!())),
- (("usart", "RX"), (quote!(crate::usart::RxPin), quote!())),
- (("usart", "CTS"), (quote!(crate::usart::CtsPin), quote!())),
- (("usart", "RTS"), (quote!(crate::usart::RtsPin), quote!())),
- (("usart", "CK"), (quote!(crate::usart::CkPin), quote!())),
- (("spi", "SCK"), (quote!(crate::spi::SckPin), quote!())),
- (("spi", "MOSI"), (quote!(crate::spi::MosiPin), quote!())),
- (("spi", "MISO"), (quote!(crate::spi::MisoPin), quote!())),
- (("i2c", "SDA"), (quote!(crate::i2c::SdaPin), quote!())),
- (("i2c", "SCL"), (quote!(crate::i2c::SclPin), quote!())),
- (("rcc", "MCO_1"), (quote!(crate::rcc::McoPin), quote!())),
- (("rcc", "MCO_2"), (quote!(crate::rcc::McoPin), quote!())),
- (("dcmi", "D0"), (quote!(crate::dcmi::D0Pin), quote!())),
- (("dcmi", "D1"), (quote!(crate::dcmi::D1Pin), quote!())),
- (("dcmi", "D2"), (quote!(crate::dcmi::D2Pin), quote!())),
- (("dcmi", "D3"), (quote!(crate::dcmi::D3Pin), quote!())),
- (("dcmi", "D4"), (quote!(crate::dcmi::D4Pin), quote!())),
- (("dcmi", "D5"), (quote!(crate::dcmi::D5Pin), quote!())),
- (("dcmi", "D6"), (quote!(crate::dcmi::D6Pin), quote!())),
- (("dcmi", "D7"), (quote!(crate::dcmi::D7Pin), quote!())),
- (("dcmi", "D8"), (quote!(crate::dcmi::D8Pin), quote!())),
- (("dcmi", "D9"), (quote!(crate::dcmi::D9Pin), quote!())),
- (("dcmi", "D10"), (quote!(crate::dcmi::D10Pin), quote!())),
- (("dcmi", "D11"), (quote!(crate::dcmi::D11Pin), quote!())),
- (("dcmi", "D12"), (quote!(crate::dcmi::D12Pin), quote!())),
- (("dcmi", "D13"), (quote!(crate::dcmi::D13Pin), quote!())),
- (("dcmi", "HSYNC"), (quote!(crate::dcmi::HSyncPin), quote!())),
- (("dcmi", "VSYNC"), (quote!(crate::dcmi::VSyncPin), quote!())),
- (("dcmi", "PIXCLK"), (quote!(crate::dcmi::PixClkPin), quote!())),
- (("otgfs", "DP"), (quote!(crate::usb_otg::DpPin), quote!())),
- (("otgfs", "DM"), (quote!(crate::usb_otg::DmPin), quote!())),
- (("otghs", "DP"), (quote!(crate::usb_otg::DpPin), quote!())),
- (("otghs", "DM"), (quote!(crate::usb_otg::DmPin), quote!())),
- (("otghs", "ULPI_CK"), (quote!(crate::usb_otg::UlpiClkPin), quote!())),
- (("otghs", "ULPI_DIR"), (quote!(crate::usb_otg::UlpiDirPin), quote!())),
- (("otghs", "ULPI_NXT"), (quote!(crate::usb_otg::UlpiNxtPin), quote!())),
- (("otghs", "ULPI_STP"), (quote!(crate::usb_otg::UlpiStpPin), quote!())),
- (("otghs", "ULPI_D0"), (quote!(crate::usb_otg::UlpiD0Pin), quote!())),
- (("otghs", "ULPI_D1"), (quote!(crate::usb_otg::UlpiD1Pin), quote!())),
- (("otghs", "ULPI_D2"), (quote!(crate::usb_otg::UlpiD2Pin), quote!())),
- (("otghs", "ULPI_D3"), (quote!(crate::usb_otg::UlpiD3Pin), quote!())),
- (("otghs", "ULPI_D4"), (quote!(crate::usb_otg::UlpiD4Pin), quote!())),
- (("otghs", "ULPI_D5"), (quote!(crate::usb_otg::UlpiD5Pin), quote!())),
- (("otghs", "ULPI_D6"), (quote!(crate::usb_otg::UlpiD6Pin), quote!())),
- (("otghs", "ULPI_D7"), (quote!(crate::usb_otg::UlpiD7Pin), quote!())),
- (("can", "TX"), (quote!(crate::can::TxPin), quote!())),
- (("can", "RX"), (quote!(crate::can::RxPin), quote!())),
- (("eth", "REF_CLK"), (quote!(crate::eth::RefClkPin), quote!(#[cfg(feature="net")]))),
- (("eth", "MDIO"), (quote!(crate::eth::MDIOPin), quote!(#[cfg(feature="net")]))),
- (("eth", "MDC"), (quote!(crate::eth::MDCPin), quote!(#[cfg(feature="net")]))),
- (("eth", "CRS_DV"), (quote!(crate::eth::CRSPin), quote!(#[cfg(feature="net")]))),
- (("eth", "RXD0"), (quote!(crate::eth::RXD0Pin), quote!(#[cfg(feature="net")]))),
- (("eth", "RXD1"), (quote!(crate::eth::RXD1Pin), quote!(#[cfg(feature="net")]))),
- (("eth", "TXD0"), (quote!(crate::eth::TXD0Pin), quote!(#[cfg(feature="net")]))),
- (("eth", "TXD1"), (quote!(crate::eth::TXD1Pin), quote!(#[cfg(feature="net")]))),
- (("eth", "TX_EN"), (quote!(crate::eth::TXEnPin), quote!(#[cfg(feature="net")]))),
- (("fmc", "A0"), (quote!(crate::fmc::A0Pin), quote!())),
- (("fmc", "A1"), (quote!(crate::fmc::A1Pin), quote!())),
- (("fmc", "A2"), (quote!(crate::fmc::A2Pin), quote!())),
- (("fmc", "A3"), (quote!(crate::fmc::A3Pin), quote!())),
- (("fmc", "A4"), (quote!(crate::fmc::A4Pin), quote!())),
- (("fmc", "A5"), (quote!(crate::fmc::A5Pin), quote!())),
- (("fmc", "A6"), (quote!(crate::fmc::A6Pin), quote!())),
- (("fmc", "A7"), (quote!(crate::fmc::A7Pin), quote!())),
- (("fmc", "A8"), (quote!(crate::fmc::A8Pin), quote!())),
- (("fmc", "A9"), (quote!(crate::fmc::A9Pin), quote!())),
- (("fmc", "A10"), (quote!(crate::fmc::A10Pin), quote!())),
- (("fmc", "A11"), (quote!(crate::fmc::A11Pin), quote!())),
- (("fmc", "A12"), (quote!(crate::fmc::A12Pin), quote!())),
- (("fmc", "A13"), (quote!(crate::fmc::A13Pin), quote!())),
- (("fmc", "A14"), (quote!(crate::fmc::A14Pin), quote!())),
- (("fmc", "A15"), (quote!(crate::fmc::A15Pin), quote!())),
- (("fmc", "A16"), (quote!(crate::fmc::A16Pin), quote!())),
- (("fmc", "A17"), (quote!(crate::fmc::A17Pin), quote!())),
- (("fmc", "A18"), (quote!(crate::fmc::A18Pin), quote!())),
- (("fmc", "A19"), (quote!(crate::fmc::A19Pin), quote!())),
- (("fmc", "A20"), (quote!(crate::fmc::A20Pin), quote!())),
- (("fmc", "A21"), (quote!(crate::fmc::A21Pin), quote!())),
- (("fmc", "A22"), (quote!(crate::fmc::A22Pin), quote!())),
- (("fmc", "A23"), (quote!(crate::fmc::A23Pin), quote!())),
- (("fmc", "A24"), (quote!(crate::fmc::A24Pin), quote!())),
- (("fmc", "A25"), (quote!(crate::fmc::A25Pin), quote!())),
- (("fmc", "D0"), (quote!(crate::fmc::D0Pin), quote!())),
- (("fmc", "D1"), (quote!(crate::fmc::D1Pin), quote!())),
- (("fmc", "D2"), (quote!(crate::fmc::D2Pin), quote!())),
- (("fmc", "D3"), (quote!(crate::fmc::D3Pin), quote!())),
- (("fmc", "D4"), (quote!(crate::fmc::D4Pin), quote!())),
- (("fmc", "D5"), (quote!(crate::fmc::D5Pin), quote!())),
- (("fmc", "D6"), (quote!(crate::fmc::D6Pin), quote!())),
- (("fmc", "D7"), (quote!(crate::fmc::D7Pin), quote!())),
- (("fmc", "D8"), (quote!(crate::fmc::D8Pin), quote!())),
- (("fmc", "D9"), (quote!(crate::fmc::D9Pin), quote!())),
- (("fmc", "D10"), (quote!(crate::fmc::D10Pin), quote!())),
- (("fmc", "D11"), (quote!(crate::fmc::D11Pin), quote!())),
- (("fmc", "D12"), (quote!(crate::fmc::D12Pin), quote!())),
- (("fmc", "D13"), (quote!(crate::fmc::D13Pin), quote!())),
- (("fmc", "D14"), (quote!(crate::fmc::D14Pin), quote!())),
- (("fmc", "D15"), (quote!(crate::fmc::D15Pin), quote!())),
- (("fmc", "D16"), (quote!(crate::fmc::D16Pin), quote!())),
- (("fmc", "D17"), (quote!(crate::fmc::D17Pin), quote!())),
- (("fmc", "D18"), (quote!(crate::fmc::D18Pin), quote!())),
- (("fmc", "D19"), (quote!(crate::fmc::D19Pin), quote!())),
- (("fmc", "D20"), (quote!(crate::fmc::D20Pin), quote!())),
- (("fmc", "D21"), (quote!(crate::fmc::D21Pin), quote!())),
- (("fmc", "D22"), (quote!(crate::fmc::D22Pin), quote!())),
- (("fmc", "D23"), (quote!(crate::fmc::D23Pin), quote!())),
- (("fmc", "D24"), (quote!(crate::fmc::D24Pin), quote!())),
- (("fmc", "D25"), (quote!(crate::fmc::D25Pin), quote!())),
- (("fmc", "D26"), (quote!(crate::fmc::D26Pin), quote!())),
- (("fmc", "D27"), (quote!(crate::fmc::D27Pin), quote!())),
- (("fmc", "D28"), (quote!(crate::fmc::D28Pin), quote!())),
- (("fmc", "D29"), (quote!(crate::fmc::D29Pin), quote!())),
- (("fmc", "D30"), (quote!(crate::fmc::D30Pin), quote!())),
- (("fmc", "D31"), (quote!(crate::fmc::D31Pin), quote!())),
- (("fmc", "DA0"), (quote!(crate::fmc::DA0Pin), quote!())),
- (("fmc", "DA1"), (quote!(crate::fmc::DA1Pin), quote!())),
- (("fmc", "DA2"), (quote!(crate::fmc::DA2Pin), quote!())),
- (("fmc", "DA3"), (quote!(crate::fmc::DA3Pin), quote!())),
- (("fmc", "DA4"), (quote!(crate::fmc::DA4Pin), quote!())),
- (("fmc", "DA5"), (quote!(crate::fmc::DA5Pin), quote!())),
- (("fmc", "DA6"), (quote!(crate::fmc::DA6Pin), quote!())),
- (("fmc", "DA7"), (quote!(crate::fmc::DA7Pin), quote!())),
- (("fmc", "DA8"), (quote!(crate::fmc::DA8Pin), quote!())),
- (("fmc", "DA9"), (quote!(crate::fmc::DA9Pin), quote!())),
- (("fmc", "DA10"), (quote!(crate::fmc::DA10Pin), quote!())),
- (("fmc", "DA11"), (quote!(crate::fmc::DA11Pin), quote!())),
- (("fmc", "DA12"), (quote!(crate::fmc::DA12Pin), quote!())),
- (("fmc", "DA13"), (quote!(crate::fmc::DA13Pin), quote!())),
- (("fmc", "DA14"), (quote!(crate::fmc::DA14Pin), quote!())),
- (("fmc", "DA15"), (quote!(crate::fmc::DA15Pin), quote!())),
- (("fmc", "SDNWE"), (quote!(crate::fmc::SDNWEPin), quote!())),
- (("fmc", "SDNCAS"), (quote!(crate::fmc::SDNCASPin), quote!())),
- (("fmc", "SDNRAS"), (quote!(crate::fmc::SDNRASPin), quote!())),
- (("fmc", "SDNE0"), (quote!(crate::fmc::SDNE0Pin), quote!())),
- (("fmc", "SDNE1"), (quote!(crate::fmc::SDNE1Pin), quote!())),
- (("fmc", "SDCKE0"), (quote!(crate::fmc::SDCKE0Pin), quote!())),
- (("fmc", "SDCKE1"), (quote!(crate::fmc::SDCKE1Pin), quote!())),
- (("fmc", "SDCLK"), (quote!(crate::fmc::SDCLKPin), quote!())),
- (("fmc", "NBL0"), (quote!(crate::fmc::NBL0Pin), quote!())),
- (("fmc", "NBL1"), (quote!(crate::fmc::NBL1Pin), quote!())),
- (("fmc", "NBL2"), (quote!(crate::fmc::NBL2Pin), quote!())),
- (("fmc", "NBL3"), (quote!(crate::fmc::NBL3Pin), quote!())),
- (("fmc", "INT"), (quote!(crate::fmc::INTPin), quote!())),
- (("fmc", "NL"), (quote!(crate::fmc::NLPin), quote!())),
- (("fmc", "NWAIT"), (quote!(crate::fmc::NWaitPin), quote!())),
- (("fmc", "NE1"), (quote!(crate::fmc::NE1Pin), quote!())),
- (("fmc", "NE2"), (quote!(crate::fmc::NE2Pin), quote!())),
- (("fmc", "NE3"), (quote!(crate::fmc::NE3Pin), quote!())),
- (("fmc", "NE4"), (quote!(crate::fmc::NE4Pin), quote!())),
- (("fmc", "NCE"), (quote!(crate::fmc::NCEPin), quote!())),
- (("fmc", "NOE"), (quote!(crate::fmc::NOEPin), quote!())),
- (("fmc", "NWE"), (quote!(crate::fmc::NWEPin), quote!())),
- (("fmc", "Clk"), (quote!(crate::fmc::ClkPin), quote!())),
- (("fmc", "BA0"), (quote!(crate::fmc::BA0Pin), quote!())),
- (("fmc", "BA1"), (quote!(crate::fmc::BA1Pin), quote!())),
- (("timer", "CH1"), (quote!(crate::pwm::Channel1Pin), quote!())),
- (("timer", "CH1N"), (quote!(crate::pwm::Channel1ComplementaryPin), quote!())),
- (("timer", "CH2"), (quote!(crate::pwm::Channel2Pin), quote!())),
- (("timer", "CH2N"), (quote!(crate::pwm::Channel2ComplementaryPin), quote!())),
- (("timer", "CH3"), (quote!(crate::pwm::Channel3Pin), quote!())),
- (("timer", "CH3N"), (quote!(crate::pwm::Channel3ComplementaryPin), quote!())),
- (("timer", "CH4"), (quote!(crate::pwm::Channel4Pin), quote!())),
- (("timer", "CH4N"), (quote!(crate::pwm::Channel4ComplementaryPin), quote!())),
- (("timer", "ETR"), (quote!(crate::pwm::ExternalTriggerPin), quote!())),
- (("timer", "BKIN"), (quote!(crate::pwm::BreakInputPin), quote!())),
- (("timer", "BKIN_COMP1"), (quote!(crate::pwm::BreakInputComparator1Pin), quote!())),
- (("timer", "BKIN_COMP2"), (quote!(crate::pwm::BreakInputComparator2Pin), quote!())),
- (("timer", "BKIN2"), (quote!(crate::pwm::BreakInput2Pin), quote!())),
- (("timer", "BKIN2_COMP1"), (quote!(crate::pwm::BreakInput2Comparator1Pin), quote!())),
- (("timer", "BKIN2_COMP2"), (quote!(crate::pwm::BreakInput2Comparator2Pin), quote!())),
- (("sdmmc", "CK"), (quote!(crate::sdmmc::CkPin), quote!())),
- (("sdmmc", "CMD"), (quote!(crate::sdmmc::CmdPin), quote!())),
- (("sdmmc", "D0"), (quote!(crate::sdmmc::D0Pin), quote!())),
- (("sdmmc", "D1"), (quote!(crate::sdmmc::D1Pin), quote!())),
- (("sdmmc", "D2"), (quote!(crate::sdmmc::D2Pin), quote!())),
- (("sdmmc", "D3"), (quote!(crate::sdmmc::D3Pin), quote!())),
- (("sdmmc", "D4"), (quote!(crate::sdmmc::D4Pin), quote!())),
- (("sdmmc", "D5"), (quote!(crate::sdmmc::D5Pin), quote!())),
- (("sdmmc", "D6"), (quote!(crate::sdmmc::D6Pin), quote!())),
- (("sdmmc", "D6"), (quote!(crate::sdmmc::D7Pin), quote!())),
- (("sdmmc", "D8"), (quote!(crate::sdmmc::D8Pin), quote!())),
+ // (kind, signal) => trait
+ (("usart", "TX"), quote!(crate::usart::TxPin)),
+ (("usart", "RX"), quote!(crate::usart::RxPin)),
+ (("usart", "CTS"), quote!(crate::usart::CtsPin)),
+ (("usart", "RTS"), quote!(crate::usart::RtsPin)),
+ (("usart", "CK"), quote!(crate::usart::CkPin)),
+ (("usart", "TX"), quote!(crate::usart::TxPin)),
+ (("usart", "RX"), quote!(crate::usart::RxPin)),
+ (("usart", "CTS"), quote!(crate::usart::CtsPin)),
+ (("usart", "RTS"), quote!(crate::usart::RtsPin)),
+ (("usart", "CK"), quote!(crate::usart::CkPin)),
+ (("spi", "SCK"), quote!(crate::spi::SckPin)),
+ (("spi", "MOSI"), quote!(crate::spi::MosiPin)),
+ (("spi", "MISO"), quote!(crate::spi::MisoPin)),
+ (("i2c", "SDA"), quote!(crate::i2c::SdaPin)),
+ (("i2c", "SCL"), quote!(crate::i2c::SclPin)),
+ (("rcc", "MCO_1"), quote!(crate::rcc::McoPin)),
+ (("rcc", "MCO_2"), quote!(crate::rcc::McoPin)),
+ (("dcmi", "D0"), quote!(crate::dcmi::D0Pin)),
+ (("dcmi", "D1"), quote!(crate::dcmi::D1Pin)),
+ (("dcmi", "D2"), quote!(crate::dcmi::D2Pin)),
+ (("dcmi", "D3"), quote!(crate::dcmi::D3Pin)),
+ (("dcmi", "D4"), quote!(crate::dcmi::D4Pin)),
+ (("dcmi", "D5"), quote!(crate::dcmi::D5Pin)),
+ (("dcmi", "D6"), quote!(crate::dcmi::D6Pin)),
+ (("dcmi", "D7"), quote!(crate::dcmi::D7Pin)),
+ (("dcmi", "D8"), quote!(crate::dcmi::D8Pin)),
+ (("dcmi", "D9"), quote!(crate::dcmi::D9Pin)),
+ (("dcmi", "D10"), quote!(crate::dcmi::D10Pin)),
+ (("dcmi", "D11"), quote!(crate::dcmi::D11Pin)),
+ (("dcmi", "D12"), quote!(crate::dcmi::D12Pin)),
+ (("dcmi", "D13"), quote!(crate::dcmi::D13Pin)),
+ (("dcmi", "HSYNC"), quote!(crate::dcmi::HSyncPin)),
+ (("dcmi", "VSYNC"), quote!(crate::dcmi::VSyncPin)),
+ (("dcmi", "PIXCLK"), quote!(crate::dcmi::PixClkPin)),
+ (("otgfs", "DP"), quote!(crate::usb_otg::DpPin)),
+ (("otgfs", "DM"), quote!(crate::usb_otg::DmPin)),
+ (("otghs", "DP"), quote!(crate::usb_otg::DpPin)),
+ (("otghs", "DM"), quote!(crate::usb_otg::DmPin)),
+ (("otghs", "ULPI_CK"), quote!(crate::usb_otg::UlpiClkPin)),
+ (("otghs", "ULPI_DIR"), quote!(crate::usb_otg::UlpiDirPin)),
+ (("otghs", "ULPI_NXT"), quote!(crate::usb_otg::UlpiNxtPin)),
+ (("otghs", "ULPI_STP"), quote!(crate::usb_otg::UlpiStpPin)),
+ (("otghs", "ULPI_D0"), quote!(crate::usb_otg::UlpiD0Pin)),
+ (("otghs", "ULPI_D1"), quote!(crate::usb_otg::UlpiD1Pin)),
+ (("otghs", "ULPI_D2"), quote!(crate::usb_otg::UlpiD2Pin)),
+ (("otghs", "ULPI_D3"), quote!(crate::usb_otg::UlpiD3Pin)),
+ (("otghs", "ULPI_D4"), quote!(crate::usb_otg::UlpiD4Pin)),
+ (("otghs", "ULPI_D5"), quote!(crate::usb_otg::UlpiD5Pin)),
+ (("otghs", "ULPI_D6"), quote!(crate::usb_otg::UlpiD6Pin)),
+ (("otghs", "ULPI_D7"), quote!(crate::usb_otg::UlpiD7Pin)),
+ (("can", "TX"), quote!(crate::can::TxPin)),
+ (("can", "RX"), quote!(crate::can::RxPin)),
+ (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)),
+ (("eth", "MDIO"), quote!(crate::eth::MDIOPin)),
+ (("eth", "MDC"), quote!(crate::eth::MDCPin)),
+ (("eth", "CRS_DV"), quote!(crate::eth::CRSPin)),
+ (("eth", "RXD0"), quote!(crate::eth::RXD0Pin)),
+ (("eth", "RXD1"), quote!(crate::eth::RXD1Pin)),
+ (("eth", "TXD0"), quote!(crate::eth::TXD0Pin)),
+ (("eth", "TXD1"), quote!(crate::eth::TXD1Pin)),
+ (("eth", "TX_EN"), quote!(crate::eth::TXEnPin)),
+ (("fmc", "A0"), quote!(crate::fmc::A0Pin)),
+ (("fmc", "A1"), quote!(crate::fmc::A1Pin)),
+ (("fmc", "A2"), quote!(crate::fmc::A2Pin)),
+ (("fmc", "A3"), quote!(crate::fmc::A3Pin)),
+ (("fmc", "A4"), quote!(crate::fmc::A4Pin)),
+ (("fmc", "A5"), quote!(crate::fmc::A5Pin)),
+ (("fmc", "A6"), quote!(crate::fmc::A6Pin)),
+ (("fmc", "A7"), quote!(crate::fmc::A7Pin)),
+ (("fmc", "A8"), quote!(crate::fmc::A8Pin)),
+ (("fmc", "A9"), quote!(crate::fmc::A9Pin)),
+ (("fmc", "A10"), quote!(crate::fmc::A10Pin)),
+ (("fmc", "A11"), quote!(crate::fmc::A11Pin)),
+ (("fmc", "A12"), quote!(crate::fmc::A12Pin)),
+ (("fmc", "A13"), quote!(crate::fmc::A13Pin)),
+ (("fmc", "A14"), quote!(crate::fmc::A14Pin)),
+ (("fmc", "A15"), quote!(crate::fmc::A15Pin)),
+ (("fmc", "A16"), quote!(crate::fmc::A16Pin)),
+ (("fmc", "A17"), quote!(crate::fmc::A17Pin)),
+ (("fmc", "A18"), quote!(crate::fmc::A18Pin)),
+ (("fmc", "A19"), quote!(crate::fmc::A19Pin)),
+ (("fmc", "A20"), quote!(crate::fmc::A20Pin)),
+ (("fmc", "A21"), quote!(crate::fmc::A21Pin)),
+ (("fmc", "A22"), quote!(crate::fmc::A22Pin)),
+ (("fmc", "A23"), quote!(crate::fmc::A23Pin)),
+ (("fmc", "A24"), quote!(crate::fmc::A24Pin)),
+ (("fmc", "A25"), quote!(crate::fmc::A25Pin)),
+ (("fmc", "D0"), quote!(crate::fmc::D0Pin)),
+ (("fmc", "D1"), quote!(crate::fmc::D1Pin)),
+ (("fmc", "D2"), quote!(crate::fmc::D2Pin)),
+ (("fmc", "D3"), quote!(crate::fmc::D3Pin)),
+ (("fmc", "D4"), quote!(crate::fmc::D4Pin)),
+ (("fmc", "D5"), quote!(crate::fmc::D5Pin)),
+ (("fmc", "D6"), quote!(crate::fmc::D6Pin)),
+ (("fmc", "D7"), quote!(crate::fmc::D7Pin)),
+ (("fmc", "D8"), quote!(crate::fmc::D8Pin)),
+ (("fmc", "D9"), quote!(crate::fmc::D9Pin)),
+ (("fmc", "D10"), quote!(crate::fmc::D10Pin)),
+ (("fmc", "D11"), quote!(crate::fmc::D11Pin)),
+ (("fmc", "D12"), quote!(crate::fmc::D12Pin)),
+ (("fmc", "D13"), quote!(crate::fmc::D13Pin)),
+ (("fmc", "D14"), quote!(crate::fmc::D14Pin)),
+ (("fmc", "D15"), quote!(crate::fmc::D15Pin)),
+ (("fmc", "D16"), quote!(crate::fmc::D16Pin)),
+ (("fmc", "D17"), quote!(crate::fmc::D17Pin)),
+ (("fmc", "D18"), quote!(crate::fmc::D18Pin)),
+ (("fmc", "D19"), quote!(crate::fmc::D19Pin)),
+ (("fmc", "D20"), quote!(crate::fmc::D20Pin)),
+ (("fmc", "D21"), quote!(crate::fmc::D21Pin)),
+ (("fmc", "D22"), quote!(crate::fmc::D22Pin)),
+ (("fmc", "D23"), quote!(crate::fmc::D23Pin)),
+ (("fmc", "D24"), quote!(crate::fmc::D24Pin)),
+ (("fmc", "D25"), quote!(crate::fmc::D25Pin)),
+ (("fmc", "D26"), quote!(crate::fmc::D26Pin)),
+ (("fmc", "D27"), quote!(crate::fmc::D27Pin)),
+ (("fmc", "D28"), quote!(crate::fmc::D28Pin)),
+ (("fmc", "D29"), quote!(crate::fmc::D29Pin)),
+ (("fmc", "D30"), quote!(crate::fmc::D30Pin)),
+ (("fmc", "D31"), quote!(crate::fmc::D31Pin)),
+ (("fmc", "DA0"), quote!(crate::fmc::DA0Pin)),
+ (("fmc", "DA1"), quote!(crate::fmc::DA1Pin)),
+ (("fmc", "DA2"), quote!(crate::fmc::DA2Pin)),
+ (("fmc", "DA3"), quote!(crate::fmc::DA3Pin)),
+ (("fmc", "DA4"), quote!(crate::fmc::DA4Pin)),
+ (("fmc", "DA5"), quote!(crate::fmc::DA5Pin)),
+ (("fmc", "DA6"), quote!(crate::fmc::DA6Pin)),
+ (("fmc", "DA7"), quote!(crate::fmc::DA7Pin)),
+ (("fmc", "DA8"), quote!(crate::fmc::DA8Pin)),
+ (("fmc", "DA9"), quote!(crate::fmc::DA9Pin)),
+ (("fmc", "DA10"), quote!(crate::fmc::DA10Pin)),
+ (("fmc", "DA11"), quote!(crate::fmc::DA11Pin)),
+ (("fmc", "DA12"), quote!(crate::fmc::DA12Pin)),
+ (("fmc", "DA13"), quote!(crate::fmc::DA13Pin)),
+ (("fmc", "DA14"), quote!(crate::fmc::DA14Pin)),
+ (("fmc", "DA15"), quote!(crate::fmc::DA15Pin)),
+ (("fmc", "SDNWE"), quote!(crate::fmc::SDNWEPin)),
+ (("fmc", "SDNCAS"), quote!(crate::fmc::SDNCASPin)),
+ (("fmc", "SDNRAS"), quote!(crate::fmc::SDNRASPin)),
+ (("fmc", "SDNE0"), quote!(crate::fmc::SDNE0Pin)),
+ (("fmc", "SDNE1"), quote!(crate::fmc::SDNE1Pin)),
+ (("fmc", "SDCKE0"), quote!(crate::fmc::SDCKE0Pin)),
+ (("fmc", "SDCKE1"), quote!(crate::fmc::SDCKE1Pin)),
+ (("fmc", "SDCLK"), quote!(crate::fmc::SDCLKPin)),
+ (("fmc", "NBL0"), quote!(crate::fmc::NBL0Pin)),
+ (("fmc", "NBL1"), quote!(crate::fmc::NBL1Pin)),
+ (("fmc", "NBL2"), quote!(crate::fmc::NBL2Pin)),
+ (("fmc", "NBL3"), quote!(crate::fmc::NBL3Pin)),
+ (("fmc", "INT"), quote!(crate::fmc::INTPin)),
+ (("fmc", "NL"), quote!(crate::fmc::NLPin)),
+ (("fmc", "NWAIT"), quote!(crate::fmc::NWaitPin)),
+ (("fmc", "NE1"), quote!(crate::fmc::NE1Pin)),
+ (("fmc", "NE2"), quote!(crate::fmc::NE2Pin)),
+ (("fmc", "NE3"), quote!(crate::fmc::NE3Pin)),
+ (("fmc", "NE4"), quote!(crate::fmc::NE4Pin)),
+ (("fmc", "NCE"), quote!(crate::fmc::NCEPin)),
+ (("fmc", "NOE"), quote!(crate::fmc::NOEPin)),
+ (("fmc", "NWE"), quote!(crate::fmc::NWEPin)),
+ (("fmc", "Clk"), quote!(crate::fmc::ClkPin)),
+ (("fmc", "BA0"), quote!(crate::fmc::BA0Pin)),
+ (("fmc", "BA1"), quote!(crate::fmc::BA1Pin)),
+ (("timer", "CH1"), quote!(crate::pwm::Channel1Pin)),
+ (("timer", "CH1N"), quote!(crate::pwm::Channel1ComplementaryPin)),
+ (("timer", "CH2"), quote!(crate::pwm::Channel2Pin)),
+ (("timer", "CH2N"), quote!(crate::pwm::Channel2ComplementaryPin)),
+ (("timer", "CH3"), quote!(crate::pwm::Channel3Pin)),
+ (("timer", "CH3N"), quote!(crate::pwm::Channel3ComplementaryPin)),
+ (("timer", "CH4"), quote!(crate::pwm::Channel4Pin)),
+ (("timer", "CH4N"), quote!(crate::pwm::Channel4ComplementaryPin)),
+ (("timer", "ETR"), quote!(crate::pwm::ExternalTriggerPin)),
+ (("timer", "BKIN"), quote!(crate::pwm::BreakInputPin)),
+ (("timer", "BKIN_COMP1"), quote!(crate::pwm::BreakInputComparator1Pin)),
+ (("timer", "BKIN_COMP2"), quote!(crate::pwm::BreakInputComparator2Pin)),
+ (("timer", "BKIN2"), quote!(crate::pwm::BreakInput2Pin)),
+ (("timer", "BKIN2_COMP1"), quote!(crate::pwm::BreakInput2Comparator1Pin)),
+ (("timer", "BKIN2_COMP2"), quote!(crate::pwm::BreakInput2Comparator2Pin)),
+ (("sdmmc", "CK"), quote!(crate::sdmmc::CkPin)),
+ (("sdmmc", "CMD"), quote!(crate::sdmmc::CmdPin)),
+ (("sdmmc", "D0"), quote!(crate::sdmmc::D0Pin)),
+ (("sdmmc", "D1"), quote!(crate::sdmmc::D1Pin)),
+ (("sdmmc", "D2"), quote!(crate::sdmmc::D2Pin)),
+ (("sdmmc", "D3"), quote!(crate::sdmmc::D3Pin)),
+ (("sdmmc", "D4"), quote!(crate::sdmmc::D4Pin)),
+ (("sdmmc", "D5"), quote!(crate::sdmmc::D5Pin)),
+ (("sdmmc", "D6"), quote!(crate::sdmmc::D6Pin)),
+ (("sdmmc", "D6"), quote!(crate::sdmmc::D7Pin)),
+ (("sdmmc", "D8"), quote!(crate::sdmmc::D8Pin)),
].into();
for p in METADATA.peripherals {
if let Some(regs) = &p.registers {
for pin in p.pins {
let key = (regs.kind, pin.signal);
- if let Some((tr, cfgs)) = signals.get(&key) {
+ if let Some(tr) = signals.get(&key) {
let mut peri = format_ident!("{}", p.name);
let pin_name = format_ident!("{}", pin.pin);
let af = pin.af.unwrap_or(0);
@@ -453,7 +453,6 @@ fn main() {
}
g.extend(quote! {
- #cfgs
pin_trait_impl!(#tr, #peri, #pin_name, #af);
})
}
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index 28f0c178..76a3dfab 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -1,10 +1,12 @@
#![macro_use]
+#[cfg(feature = "net")]
#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
#[cfg_attr(eth_v2, path = "v2/mod.rs")]
mod _version;
pub mod generic_smi;
+#[cfg(feature = "net")]
pub use _version::*;
/// Station Management Interface (SMI) on an ethernet PHY
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 6e9077b4..86b3e25d 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -39,7 +39,7 @@ pub mod can;
pub mod dac;
#[cfg(dcmi)]
pub mod dcmi;
-#[cfg(all(eth, feature = "net"))]
+#[cfg(eth)]
pub mod eth;
#[cfg(feature = "exti")]
pub mod exti;
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
new file mode 100644
index 00000000..b2fcb504
--- /dev/null
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -0,0 +1,238 @@
+use atomic_polyfill::{compiler_fence, Ordering};
+use core::future::Future;
+use core::task::Poll;
+use embassy::waitqueue::WakerRegistration;
+use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
+use embassy_hal_common::ring_buffer::RingBuffer;
+use futures::future::poll_fn;
+
+use super::*;
+
+pub struct State<'d, T: Instance>(StateStorage<StateInner<'d, T>>);
+impl<'d, T: Instance> State<'d, T> {
+ pub fn new() -> Self {
+ Self(StateStorage::new())
+ }
+}
+
+struct StateInner<'d, T: Instance> {
+ phantom: PhantomData<&'d mut T>,
+
+ rx_waker: WakerRegistration,
+ rx: RingBuffer<'d>,
+
+ tx_waker: WakerRegistration,
+ tx: RingBuffer<'d>,
+}
+
+unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {}
+unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {}
+
+pub struct BufferedUart<'d, T: Instance> {
+ inner: PeripheralMutex<'d, StateInner<'d, T>>,
+}
+
+impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {}
+
+impl<'d, T: Instance> BufferedUart<'d, T> {
+ pub unsafe fn new(
+ state: &'d mut State<'d, T>,
+ _uart: Uart<'d, T, NoDma, NoDma>,
+ irq: impl Unborrow<Target = T::Interrupt> + 'd,
+ tx_buffer: &'d mut [u8],
+ rx_buffer: &'d mut [u8],
+ ) -> BufferedUart<'d, T> {
+ unborrow!(irq);
+
+ let r = T::regs();
+ r.cr1().modify(|w| {
+ w.set_rxneie(true);
+ w.set_idleie(true);
+ });
+
+ Self {
+ inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner {
+ phantom: PhantomData,
+ tx: RingBuffer::new(tx_buffer),
+ tx_waker: WakerRegistration::new(),
+
+ rx: RingBuffer::new(rx_buffer),
+ rx_waker: WakerRegistration::new(),
+ }),
+ }
+ }
+}
+
+impl<'d, T: Instance> StateInner<'d, T>
+where
+ Self: 'd,
+{
+ fn on_rx(&mut self) {
+ let r = T::regs();
+ unsafe {
+ let sr = sr(r).read();
+ clear_interrupt_flags(r, sr);
+
+ // This read also clears the error and idle interrupt flags on v1.
+ let b = rdr(r).read_volatile();
+
+ if sr.rxne() {
+ if sr.pe() {
+ warn!("Parity error");
+ }
+ if sr.fe() {
+ warn!("Framing error");
+ }
+ if sr.ne() {
+ warn!("Noise error");
+ }
+ if sr.ore() {
+ warn!("Overrun error");
+ }
+
+ let buf = self.rx.push_buf();
+ if !buf.is_empty() {
+ buf[0] = b;
+ self.rx.push(1);
+ } else {
+ warn!("RX buffer full, discard received byte");
+ }
+
+ if self.rx.is_full() {
+ self.rx_waker.wake();
+ }
+ }
+
+ if sr.idle() {
+ self.rx_waker.wake();
+ };
+ }
+ }
+
+ fn on_tx(&mut self) {
+ let r = T::regs();
+ unsafe {
+ if sr(r).read().txe() {
+ let buf = self.tx.pop_buf();
+ if !buf.is_empty() {
+ r.cr1().modify(|w| {
+ w.set_txeie(true);
+ });
+ tdr(r).write_volatile(buf[0].into());
+ self.tx.pop(1);
+ self.tx_waker.wake();
+ } else {
+ // Disable interrupt until we have something to transmit again
+ r.cr1().modify(|w| {
+ w.set_txeie(false);
+ });
+ }
+ }
+ }
+ }
+}
+
+impl<'d, T: Instance> PeripheralState for StateInner<'d, T>
+where
+ Self: 'd,
+{
+ type Interrupt = T::Interrupt;
+ fn on_interrupt(&mut self) {
+ self.on_rx();
+ self.on_tx();
+ }
+}
+
+impl embedded_io::Error for Error {
+ fn kind(&self) -> embedded_io::ErrorKind {
+ embedded_io::ErrorKind::Other
+ }
+}
+
+impl<'d, T: Instance> embedded_io::Io for BufferedUart<'d, T> {
+ type Error = Error;
+}
+
+impl<'d, T: Instance> embedded_io::asynch::Read for BufferedUart<'d, T> {
+ type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
+ where
+ Self: 'a;
+
+ fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
+ poll_fn(move |cx| {
+ let mut do_pend = false;
+ let res = self.inner.with(|state| {
+ compiler_fence(Ordering::SeqCst);
+
+ // We have data ready in buffer? Return it.
+ let data = state.rx.pop_buf();
+ if !data.is_empty() {
+ let len = data.len().min(buf.len());
+ buf[..len].copy_from_slice(&data[..len]);
+
+ if state.rx.is_full() {
+ do_pend = true;
+ }
+ state.rx.pop(len);
+
+ return Poll::Ready(Ok(len));
+ }
+
+ state.rx_waker.register(cx.waker());
+ Poll::Pending
+ });
+
+ if do_pend {
+ self.inner.pend();
+ }
+
+ res
+ })
+ }
+}
+
+impl<'d, T: Instance> embedded_io::asynch::Write for BufferedUart<'d, T> {
+ type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
+ where
+ Self: 'a;
+
+ fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
+ poll_fn(move |cx| {
+ let (poll, empty) = self.inner.with(|state| {
+ let empty = state.tx.is_empty();
+ let tx_buf = state.tx.push_buf();
+ if tx_buf.is_empty() {
+ state.tx_waker.register(cx.waker());
+ return (Poll::Pending, empty);
+ }
+
+ let n = core::cmp::min(tx_buf.len(), buf.len());
+ tx_buf[..n].copy_from_slice(&buf[..n]);
+ state.tx.push(n);
+
+ (Poll::Ready(Ok(n)), empty)
+ });
+ if empty {
+ self.inner.pend();
+ }
+ poll
+ })
+ }
+
+ type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
+ where
+ Self: 'a;
+
+ fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
+ poll_fn(move |cx| {
+ self.inner.with(|state| {
+ if !state.tx.is_empty() {
+ state.tx_waker.register(cx.waker());
+ return Poll::Pending;
+ }
+
+ Poll::Ready(Ok(()))
+ })
+ })
+ }
+}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 22224215..6feecd18 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -424,227 +424,10 @@ cfg_if::cfg_if! {
}
}
+#[cfg(feature = "nightly")]
pub use buffered::*;
-mod buffered {
- use atomic_polyfill::{compiler_fence, Ordering};
- use core::pin::Pin;
- use core::task::Context;
- use core::task::Poll;
- use embassy::waitqueue::WakerRegistration;
- use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
- use embassy_hal_common::ring_buffer::RingBuffer;
-
- use super::*;
-
- pub struct State<'d, T: Instance>(StateStorage<StateInner<'d, T>>);
- impl<'d, T: Instance> State<'d, T> {
- pub fn new() -> Self {
- Self(StateStorage::new())
- }
- }
-
- struct StateInner<'d, T: Instance> {
- phantom: PhantomData<&'d mut T>,
-
- rx_waker: WakerRegistration,
- rx: RingBuffer<'d>,
-
- tx_waker: WakerRegistration,
- tx: RingBuffer<'d>,
- }
-
- unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {}
- unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {}
-
- pub struct BufferedUart<'d, T: Instance> {
- inner: PeripheralMutex<'d, StateInner<'d, T>>,
- }
-
- impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {}
-
- impl<'d, T: Instance> BufferedUart<'d, T> {
- pub unsafe fn new(
- state: &'d mut State<'d, T>,
- _uart: Uart<'d, T, NoDma, NoDma>,
- irq: impl Unborrow<Target = T::Interrupt> + 'd,
- tx_buffer: &'d mut [u8],
- rx_buffer: &'d mut [u8],
- ) -> BufferedUart<'d, T> {
- unborrow!(irq);
-
- let r = T::regs();
- r.cr1().modify(|w| {
- w.set_rxneie(true);
- w.set_idleie(true);
- });
-
- Self {
- inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner {
- phantom: PhantomData,
- tx: RingBuffer::new(tx_buffer),
- tx_waker: WakerRegistration::new(),
-
- rx: RingBuffer::new(rx_buffer),
- rx_waker: WakerRegistration::new(),
- }),
- }
- }
- }
-
- impl<'d, T: Instance> StateInner<'d, T>
- where
- Self: 'd,
- {
- fn on_rx(&mut self) {
- let r = T::regs();
- unsafe {
- let sr = sr(r).read();
- clear_interrupt_flags(r, sr);
-
- // This read also clears the error and idle interrupt flags on v1.
- let b = rdr(r).read_volatile();
-
- if sr.rxne() {
- if sr.pe() {
- warn!("Parity error");
- }
- if sr.fe() {
- warn!("Framing error");
- }
- if sr.ne() {
- warn!("Noise error");
- }
- if sr.ore() {
- warn!("Overrun error");
- }
-
- let buf = self.rx.push_buf();
- if !buf.is_empty() {
- buf[0] = b;
- self.rx.push(1);
- } else {
- warn!("RX buffer full, discard received byte");
- }
-
- if self.rx.is_full() {
- self.rx_waker.wake();
- }
- }
-
- if sr.idle() {
- self.rx_waker.wake();
- };
- }
- }
-
- fn on_tx(&mut self) {
- let r = T::regs();
- unsafe {
- if sr(r).read().txe() {
- let buf = self.tx.pop_buf();
- if !buf.is_empty() {
- r.cr1().modify(|w| {
- w.set_txeie(true);
- });
- tdr(r).write_volatile(buf[0].into());
- self.tx.pop(1);
- self.tx_waker.wake();
- } else {
- // Disable interrupt until we have something to transmit again
- r.cr1().modify(|w| {
- w.set_txeie(false);
- });
- }
- }
- }
- }
- }
-
- impl<'d, T: Instance> PeripheralState for StateInner<'d, T>
- where
- Self: 'd,
- {
- type Interrupt = T::Interrupt;
- fn on_interrupt(&mut self) {
- self.on_rx();
- self.on_tx();
- }
- }
-
- impl<'d, T: Instance> embassy::io::AsyncBufRead for BufferedUart<'d, T> {
- fn poll_fill_buf(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- ) -> Poll<Result<&[u8], embassy::io::Error>> {
- self.inner.with(|state| {
- compiler_fence(Ordering::SeqCst);
-
- // We have data ready in buffer? Return it.
- let buf = state.rx.pop_buf();
- if !buf.is_empty() {
- let buf: &[u8] = buf;
- // Safety: buffer lives as long as uart
- let buf: &[u8] = unsafe { core::mem::transmute(buf) };
- return Poll::Ready(Ok(buf));
- }
-
- state.rx_waker.register(cx.waker());
- Poll::<Result<&[u8], embassy::io::Error>>::Pending
- })
- }
- fn consume(mut self: Pin<&mut Self>, amt: usize) {
- let signal = self.inner.with(|state| {
- let full = state.rx.is_full();
- state.rx.pop(amt);
- full
- });
- if signal {
- self.inner.pend();
- }
- }
- }
-
- impl<'d, T: Instance> embassy::io::AsyncWrite for BufferedUart<'d, T> {
- fn poll_write(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<Result<usize, embassy::io::Error>> {
- let (poll, empty) = self.inner.with(|state| {
- let empty = state.tx.is_empty();
- let tx_buf = state.tx.push_buf();
- if tx_buf.is_empty() {
- state.tx_waker.register(cx.waker());
- return (Poll::Pending, empty);
- }
-
- let n = core::cmp::min(tx_buf.len(), buf.len());
- tx_buf[..n].copy_from_slice(&buf[..n]);
- state.tx.push(n);
-
- (Poll::Ready(Ok(n)), empty)
- });
- if empty {
- self.inner.pend();
- }
- poll
- }
-
- fn poll_flush(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- ) -> Poll<Result<(), embassy::io::Error>> {
- self.inner.with(|state| {
- if !state.tx.is_empty() {
- state.tx_waker.register(cx.waker());
- return Poll::Pending;
- }
-
- Poll::Ready(Ok(()))
- })
- }
- }
-}
+#[cfg(feature = "nightly")]
+mod buffered;
#[cfg(usart_v1)]
fn tdr(r: crate::pac::usart::Usart) -> *mut u8 {
@@ -662,6 +445,7 @@ fn sr(r: crate::pac::usart::Usart) -> crate::pac::common::Reg<regs::Sr, crate::p
}
#[cfg(usart_v1)]
+#[allow(unused)]
unsafe fn clear_interrupt_flags(_r: crate::pac::usart::Usart, _sr: regs::Sr) {
// On v1 the flags are cleared implicitly by reads and writes to DR.
}
@@ -682,6 +466,7 @@ fn sr(r: crate::pac::usart::Usart) -> crate::pac::common::Reg<regs::Ixr, crate::
}
#[cfg(usart_v2)]
+#[allow(unused)]
unsafe fn clear_interrupt_flags(r: crate::pac::usart::Usart, sr: regs::Ixr) {
r.icr().write(|w| *w = sr);
}
diff --git a/embassy/src/io/error.rs b/embassy/src/io/error.rs
deleted file mode 100644
index 2092c0d1..00000000
--- a/embassy/src/io/error.rs
+++ /dev/null
@@ -1,142 +0,0 @@
-/// Categories of errors that can occur.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
-#[non_exhaustive]
-pub enum Error {
- /// An entity was not found, often a file.
- NotFound,
- /// The operation lacked the necessary privileges to complete.
- PermissionDenied,
- /// The connection was refused by the remote server.
- ConnectionRefused,
- /// The connection was reset by the remote server.
- ConnectionReset,
- /// The connection was aborted (terminated) by the remote server.
- ConnectionAborted,
- /// The network operation failed because it was not connected yet.
- NotConnected,
- /// A socket address could not be bound because the address is already in
- /// use elsewhere.
- AddrInUse,
- /// A nonexistent interface was requested or the requested address was not
- /// local.
- AddrNotAvailable,
- /// The operation failed because a pipe was closed.
- BrokenPipe,
- /// An entity already exists, often a file.
- AlreadyExists,
- /// The operation needs to block to complete, but the blocking operation was
- /// requested to not occur.
- WouldBlock,
- /// A parameter was incorrect.
- InvalidInput,
- /// Data not valid for the operation were encountered.
- ///
- /// Unlike [`InvalidInput`], this typically means that the operation
- /// parameters were valid, however the error was caused by malformed
- /// input data.
- ///
- /// For example, a function that reads a file into a string will error with
- /// `InvalidData` if the file's contents are not valid UTF-8.
- ///
- /// [`InvalidInput`]: #variant.InvalidInput
- InvalidData,
- /// The I/O operation's timeout expired, causing it to be canceled.
- TimedOut,
- /// An error returned when an operation could not be completed because a
- /// call to [`write`] returned [`Ok(0)`].
- ///
- /// This typically means that an operation could only succeed if it wrote a
- /// particular number of bytes but only a smaller number of bytes could be
- /// written.
- ///
- /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
- /// [`Ok(0)`]: ../../std/io/type.Result.html
- WriteZero,
- /// This operation was interrupted.
- ///
- /// Interrupted operations can typically be retried.
- Interrupted,
-
- /// An error returned when an operation could not be completed because an
- /// "end of file" was reached prematurely.
- ///
- /// This typically means that an operation could only succeed if it read a
- /// particular number of bytes but only a smaller number of bytes could be
- /// read.
- UnexpectedEof,
-
- /// An operation would have read more data if the given buffer was large.
- ///
- /// This typically means that the buffer has been filled with the first N bytes
- /// of the read data.
- Truncated,
-
- /// Any I/O error not part of this list.
- Other,
-}
-
-pub type Result<T> = core::result::Result<T, Error>;
-
-#[cfg(feature = "std")]
-impl From<std::io::Error> for Error {
- fn from(err: std::io::Error) -> Error {
- match err.kind() {
- std::io::ErrorKind::NotFound => Error::NotFound,
- std::io::ErrorKind::PermissionDenied => Error::PermissionDenied,
- std::io::ErrorKind::ConnectionRefused => Error::ConnectionRefused,
- std::io::ErrorKind::ConnectionReset => Error::ConnectionReset,
- std::io::ErrorKind::ConnectionAborted => Error::ConnectionAborted,
- std::io::ErrorKind::NotConnected => Error::NotConnected,
- std::io::ErrorKind::AddrInUse => Error::AddrInUse,
- std::io::ErrorKind::AddrNotAvailable => Error::AddrNotAvailable,
- std::io::ErrorKind::BrokenPipe => Error::BrokenPipe,
- std::io::ErrorKind::AlreadyExists => Error::AlreadyExists,
- std::io::ErrorKind::WouldBlock => Error::WouldBlock,
- std::io::ErrorKind::InvalidInput => Error::InvalidInput,
- std::io::ErrorKind::InvalidData => Error::InvalidData,
- std::io::ErrorKind::TimedOut => Error::TimedOut,
- std::io::ErrorKind::WriteZero => Error::WriteZero,
- std::io::ErrorKind::Interrupted => Error::Interrupted,
- std::io::ErrorKind::UnexpectedEof => Error::UnexpectedEof,
- _ => Error::Other,
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl From<Error> for std::io::Error {
- fn from(e: Error) -> Self {
- let kind = match e {
- Error::NotFound => std::io::ErrorKind::NotFound,
- Error::PermissionDenied => std::io::ErrorKind::PermissionDenied,
- Error::ConnectionRefused => std::io::ErrorKind::ConnectionRefused,
- Error::ConnectionReset => std::io::ErrorKind::ConnectionReset,
- Error::ConnectionAborted => std::io::ErrorKind::ConnectionAborted,
- Error::NotConnected => std::io::ErrorKind::NotConnected,
- Error::AddrInUse => std::io::ErrorKind::AddrInUse,
- Error::AddrNotAvailable => std::io::ErrorKind::AddrNotAvailable,
- Error::BrokenPipe => std::io::ErrorKind::BrokenPipe,
- Error::AlreadyExists => std::io::ErrorKind::AlreadyExists,
- Error::WouldBlock => std::io::ErrorKind::WouldBlock,
- Error::InvalidInput => std::io::ErrorKind::InvalidInput,
- Error::InvalidData => std::io::ErrorKind::InvalidData,
- Error::TimedOut => std::io::ErrorKind::TimedOut,
- Error::WriteZero => std::io::ErrorKind::WriteZero,
- Error::Interrupted => std::io::ErrorKind::Interrupted,
- Error::UnexpectedEof => std::io::ErrorKind::UnexpectedEof,
- Error::Truncated => std::io::ErrorKind::Other,
- Error::Other => std::io::ErrorKind::Other,
- };
- std::io::Error::new(kind, "embassy::io::Error")
- }
-}
-
-impl core::fmt::Display for Error {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- write!(f, "{:?}", self)
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for Error {}
diff --git a/embassy/src/io/mod.rs b/embassy/src/io/mod.rs
deleted file mode 100644
index 52b05097..00000000
--- a/embassy/src/io/mod.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-mod error;
-#[cfg(feature = "std")]
-mod std;
-mod traits;
-mod util;
-
-pub use self::error::*;
-#[cfg(feature = "std")]
-pub use self::std::*;
-pub use self::traits::*;
-pub use self::util::*;
diff --git a/embassy/src/io/std.rs b/embassy/src/io/std.rs
deleted file mode 100644
index 580d5289..00000000
--- a/embassy/src/io/std.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use core::pin::Pin;
-use core::task::{Context, Poll};
-use futures::io as std_io;
-
-use super::{AsyncBufRead, AsyncWrite, Result};
-
-pub struct FromStdIo<T>(T);
-
-impl<T> FromStdIo<T> {
- pub fn new(inner: T) -> Self {
- Self(inner)
- }
-}
-
-impl<T: std_io::AsyncBufRead> AsyncBufRead for FromStdIo<T> {
- fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
- let Self(inner) = unsafe { self.get_unchecked_mut() };
- unsafe { Pin::new_unchecked(inner) }
- .poll_fill_buf(cx)
- .map_err(|e| e.into())
- }
- fn consume(self: Pin<&mut Self>, amt: usize) {
- let Self(inner) = unsafe { self.get_unchecked_mut() };
- unsafe { Pin::new_unchecked(inner) }.consume(amt)
- }
-}
-
-impl<T: std_io::AsyncWrite> AsyncWrite for FromStdIo<T> {
- fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
- let Self(inner) = unsafe { self.get_unchecked_mut() };
- unsafe { Pin::new_unchecked(inner) }
- .poll_write(cx, buf)
- .map_err(|e| e.into())
- }
- fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- let Self(inner) = unsafe { self.get_unchecked_mut() };
- unsafe { Pin::new_unchecked(inner) }
- .poll_flush(cx)
- .map_err(|e| e.into())
- }
-}
diff --git a/embassy/src/io/traits.rs b/embassy/src/io/traits.rs
deleted file mode 100644
index 06500a68..00000000
--- a/embassy/src/io/traits.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use core::ops::DerefMut;
-use core::pin::Pin;
-use core::task::{Context, Poll};
-
-#[cfg(feature = "alloc")]
-use alloc::boxed::Box;
-
-use super::error::Result;
-
-/// Read bytes asynchronously.
-///
-/// This trait is analogous to the `std::io::BufRead` trait, but integrates
-/// with the asynchronous task system. In particular, the `poll_fill_buf`
-/// method, unlike `BufRead::fill_buf`, will automatically queue the current task
-/// for wakeup and return if data is not yet available, rather than blocking
-/// the calling thread.
-pub trait AsyncBufRead {
- /// Attempt to return the contents of the internal buffer, filling it with more data
- /// from the inner reader if it is empty.
- ///
- /// On success, returns `Poll::Ready(Ok(buf))`.
- ///
- /// If no data is available for reading, the method returns
- /// `Poll::Pending` and arranges for the current task (via
- /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes
- /// readable or is closed.
- ///
- /// This function is a lower-level call. It needs to be paired with the
- /// [`consume`] method to function properly. When calling this
- /// method, none of the contents will be "read" in the sense that later
- /// calling [`poll_fill_buf`] may return the same contents. As such, [`consume`] must
- /// be called with the number of bytes that are consumed from this buffer to
- /// ensure that the bytes are never returned twice.
- ///
- /// [`poll_fill_buf`]: AsyncBufRead::poll_fill_buf
- /// [`consume`]: AsyncBufRead::consume
- ///
- /// An empty buffer returned indicates that the stream has reached EOF.
- ///
- /// # Implementation
- ///
- /// This function may not return errors of kind `WouldBlock` or
- /// `Interrupted`. Implementations must convert `WouldBlock` into
- /// `Poll::Pending` and either internally retry or convert
- /// `Interrupted` into another error kind.
- fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>>;
-
- /// Tells this buffer that `amt` bytes have been consumed from the buffer,
- /// so they should no longer be returned in calls to [`poll_fill_buf`].
- ///
- /// This function is a lower-level call. It needs to be paired with the
- /// [`poll_fill_buf`] method to function properly. This function does
- /// not perform any I/O, it simply informs this object that some amount of
- /// its buffer, returned from [`poll_fill_buf`], has been consumed and should
- /// no longer be returned. As such, this function may do odd things if
- /// [`poll_fill_buf`] isn't called before calling it.
- ///
- /// The `amt` must be `<=` the number of bytes in the buffer returned by
- /// [`poll_fill_buf`].
- ///
- /// [`poll_fill_buf`]: AsyncBufRead::poll_fill_buf
- fn consume(self: Pin<&mut Self>, amt: usize);
-}
-
-/// Write bytes asynchronously.
-///
-/// This trait is analogous to the `core::io::Write` trait, but integrates
-/// with the asynchronous task system. In particular, the `poll_write`
-/// method, unlike `Write::write`, will automatically queue the current task
-/// for wakeup and return if the writer cannot take more data, rather than blocking
-/// the calling thread.
-pub trait AsyncWrite {
- /// Attempt to write bytes from `buf` into the object.
- ///
- /// On success, returns `Poll::Ready(Ok(num_bytes_written))`.
- ///
- /// If the object is not ready for writing, the method returns
- /// `Poll::Pending` and arranges for the current task (via
- /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes
- /// writable or is closed.
- ///
- /// # Implementation
- ///
- /// This function may not return errors of kind `WouldBlock` or
- /// `Interrupted`. Implementations must convert `WouldBlock` into
- /// `Poll::Pending` and either internally retry or convert
- /// `Interrupted` into another error kind.
- ///
- /// `poll_write` must try to make progress by flushing the underlying object if
- /// that is the only way the underlying object can become writable again.
- fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>;
-
- /// Attempt to flush the object, ensuring that any buffered data reach their destination.
- ///
- /// On success, returns Poll::Ready(Ok(())).
- ///
- /// If flushing cannot immediately complete, this method returns [Poll::Pending] and arranges for the
- /// current task (via cx.waker()) to receive a notification when the object can make progress
- /// towards flushing.
- fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>;
-}
-
-macro_rules! defer_async_read {
- () => {
- fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
- Pin::new(&mut **self.get_mut()).poll_fill_buf(cx)
- }
-
- fn consume(mut self: Pin<&mut Self>, amt: usize) {
- Pin::new(&mut **self).consume(amt)
- }
- };
-}
-
-#[cfg(feature = "alloc")]
-impl<T: ?Sized + AsyncBufRead + Unpin> AsyncBufRead for Box<T> {
- defer_async_read!();
-}
-
-impl<T: ?Sized + AsyncBufRead + Unpin> AsyncBufRead for &mut T {
- defer_async_read!();
-}
-
-impl<P> AsyncBufRead for Pin<P>
-where
- P: DerefMut + Unpin,
- P::Target: AsyncBufRead,
-{
- fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
- self.get_mut().as_mut().poll_fill_buf(cx)
- }
-
- fn consume(self: Pin<&mut Self>, amt: usize) {
- self.get_mut().as_mut().consume(amt)
- }
-}
-
-macro_rules! deref_async_write {
- () => {
- fn poll_write(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &[u8],
- ) -> Poll<Result<usize>> {
- Pin::new(&mut **self).poll_write(cx, buf)
- }
-
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- Pin::new(&mut **self).poll_flush(cx)
- }
- };
-}
-
-#[cfg(feature = "alloc")]
-impl<T: ?Sized + AsyncWrite + Unpin> AsyncWrite for Box<T> {
- deref_async_write!();
-}
-
-impl<T: ?Sized + AsyncWrite + Unpin> AsyncWrite for &mut T {
- deref_async_write!();
-}
-
-impl<P> AsyncWrite for Pin<P>
-where
- P: DerefMut + Unpin,
- P::Target: AsyncWrite,
-{
- fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
- self.get_mut().as_mut().poll_write(cx, buf)
- }
-
- fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- self.get_mut().as_mut().poll_flush(cx)
- }
-}
diff --git a/embassy/src/io/util/copy_buf.rs b/embassy/src/io/util/copy_buf.rs
deleted file mode 100644
index 6d7932a0..00000000
--- a/embassy/src/io/util/copy_buf.rs
+++ /dev/null
@@ -1,80 +0,0 @@
-use core::future::Future;
-use core::pin::Pin;
-use core::task::{Context, Poll};
-use futures::ready;
-use pin_project::pin_project;
-
-use crate::io::{AsyncBufRead, AsyncWrite, Error, Result};
-
-/// Creates a future which copies all the bytes from one object to another.
-///
-/// The returned future will copy all the bytes read from this `AsyncBufRead` into the
-/// `writer` specified. This future will only complete once the `reader` has hit
-/// EOF and all bytes have been written to and flushed from the `writer`
-/// provided.
-///
-/// On success the number of bytes is returned.
-///
-/// # Examples
-///
-/// ``` ignore
-/// # futures::executor::block_on(async {
-/// use futures::io::{self, AsyncWriteExt, Cursor};
-///
-/// let reader = Cursor::new([1, 2, 3, 4]);
-/// let mut writer = Cursor::new(vec![0u8; 5]);
-///
-/// let bytes = io::copy_buf(reader, &mut writer).await?;
-/// writer.close().await?;
-///
-/// assert_eq!(bytes, 4);
-/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]);
-/// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap();
-/// ```
-pub fn copy_buf<R, W>(reader: R, writer: &mut W) -> CopyBuf<'_, R, W>
-where
- R: AsyncBufRead,
- W: AsyncWrite + Unpin + ?Sized,
-{
- CopyBuf {
- reader,
- writer,
- amt: 0,
- }
-}
-
-/// Future for the [`copy_buf()`] function.
-#[pin_project]
-#[derive(Debug)]
-#[must_use = "futures do nothing unless you `.await` or poll them"]
-pub struct CopyBuf<'a, R, W: ?Sized> {
- #[pin]
- reader: R,
- writer: &'a mut W,
- amt: usize,
-}
-
-impl<R, W> Future for CopyBuf<'_, R, W>
-where
- R: AsyncBufRead,
- W: AsyncWrite + Unpin + ?Sized,
-{
- type Output = Result<usize>;
-
- fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let mut this = self.project();
- loop {
- let buffer = ready!(this.reader.as_mut().poll_fill_buf(cx))?;
- if buffer.is_empty() {
- return Poll::Ready(Ok(*this.amt));
- }
-
- let i = ready!(Pin::new(&mut this.writer).poll_write(cx, buffer))?;
- if i == 0 {
- return Poll::Ready(Err(Error::WriteZero));
- }
- *this.amt += i;
- this.reader.as_mut().consume(i);
- }
- }
-}
diff --git a/embassy/src/io/util/drain.rs b/embassy/src/io/util/drain.rs
deleted file mode 100644
index 2542876d..00000000
--- a/embassy/src/io/util/drain.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use core::pin::Pin;
-use futures::future::Future;
-use futures::task::{Context, Poll};
-
-use super::super::error::Result;
-use super::super::traits::AsyncBufRead;
-
-pub struct Drain<'a, R: ?Sized> {
- reader: &'a mut R,
-}
-
-impl<R: ?Sized + Unpin> Unpin for Drain<'_, R> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> Drain<'a, R> {
- pub(super) fn new(reader: &'a mut R) -> Self {
- Self { reader }
- }
-}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> Future for Drain<'a, R> {
- type Output = Result<usize>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let Self { reader } = &mut *self;
- let mut reader = Pin::new(reader);
-
- let mut n = 0;
-
- loop {
- match reader.as_mut().poll_fill_buf(cx) {
- Poll::Pending => return Poll::Ready(Ok(n)),
- Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
- Poll::Ready(Ok(buf)) => {
- let len = buf.len();
- n += len;
- reader.as_mut().consume(len);
- }
- }
- }
- }
-}
diff --git a/embassy/src/io/util/flush.rs b/embassy/src/io/util/flush.rs
deleted file mode 100644
index 966ef10f..00000000
--- a/embassy/src/io/util/flush.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::Result;
-use super::super::traits::AsyncWrite;
-
-/// Future for the [`flush`](super::AsyncWriteExt::flush) method.
-#[derive(Debug)]
-#[must_use = "futures do nothing unless you `.await` or poll them"]
-pub struct Flush<'a, W: ?Sized> {
- writer: &'a mut W,
-}
-
-impl<W: ?Sized + Unpin> Unpin for Flush<'_, W> {}
-
-impl<'a, W: AsyncWrite + ?Sized + Unpin> Flush<'a, W> {
- pub(super) fn new(writer: &'a mut W) -> Self {
- Flush { writer }
- }
-}
-
-impl<W: AsyncWrite + ?Sized + Unpin> Future for Flush<'_, W> {
- type Output = Result<()>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- let this = &mut *self;
- let _ = ready!(Pin::new(&mut this.writer).poll_flush(cx))?;
- Poll::Ready(Ok(()))
- }
-}
diff --git a/embassy/src/io/util/mod.rs b/embassy/src/io/util/mod.rs
deleted file mode 100644
index 49758ba9..00000000
--- a/embassy/src/io/util/mod.rs
+++ /dev/null
@@ -1,177 +0,0 @@
-use core::cmp::min;
-use core::pin::Pin;
-use core::task::{Context, Poll};
-use futures::ready;
-
-mod read;
-pub use self::read::Read;
-
-mod read_buf;
-pub use self::read_buf::ReadBuf;
-
-mod read_byte;
-pub use self::read_byte::ReadByte;
-
-mod read_exact;
-pub use self::read_exact::ReadExact;
-
-mod read_while;
-pub use self::read_while::ReadWhile;
-
-mod read_to_end;
-pub use self::read_to_end::ReadToEnd;
-
-mod skip_while;
-pub use self::skip_while::SkipWhile;
-
-mod drain;
-pub use self::drain::Drain;
-
-mod flush;
-pub use self::flush::Flush;
-
-mod write;
-pub use self::write::Write;
-
-mod write_all;
-pub use self::write_all::WriteAll;
-
-mod write_byte;
-pub use self::write_byte::WriteByte;
-
-#[cfg(feature = "alloc")]
-mod split;
-#[cfg(feature = "alloc")]
-pub use self::split::{split, ReadHalf, WriteHalf};
-
-mod copy_buf;
-pub use self::copy_buf::{copy_buf, CopyBuf};
-
-use super::error::Result;
-use super::traits::{AsyncBufRead, AsyncWrite};
-
-pub trait AsyncBufReadExt: AsyncBufRead {
- fn poll_read(
- mut self: Pin<&mut Self>,
- cx: &mut Context<'_>,
- buf: &mut [u8],
- ) -> Poll<Result<usize>>
- where
- Self: Unpin,
- {
- let mut this = &mut *self;
- let rbuf = ready!(Pin::new(&mut this).poll_fill_buf(cx))?;
- let n = min(buf.len(), rbuf.len());
- buf[..n].copy_from_slice(&rbuf[..n]);
- Pin::new(&mut this).consume(n);
- Poll::Ready(Ok(n))
- }
-
- fn read_while<'a, F: Fn(u8) -> bool>(
- &'a mut self,
- buf: &'a mut [u8],
- f: F,
- ) -> ReadWhile<'a, Self, F>
- where
- Self: Unpin,
- {
- ReadWhile::new(self, f, buf)
- }
-
- fn skip_while<F: Fn(u8) -> bool>(&mut self, f: F) -> SkipWhile<Self, F>
- where
- Self: Unpin,
- {
- SkipWhile::new(self, f)
- }
-
- fn drain(&mut self) -> Drain<Self>
- where
- Self: Unpin,
- {
- Drain::new(self)
- }
-
- fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
- where
- Self: Unpin,
- {
- Read::new(self, buf)
- }
-
- fn read_buf(&mut self) -> ReadBuf<Self>
- where
- Self: Unpin,
- {
- ReadBuf::new(self)
- }
-
- fn read_byte(&mut self) -> ReadByte<Self>
- where
- Self: Unpin,
- {
- ReadByte::new(self)
- }
-
- fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
- where
- Self: Unpin,
- {
- ReadExact::new(self, buf)
- }
-
- fn read_to_end<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadToEnd<'a, Self>
- where
- Self: Unpin,
- {
- ReadToEnd::new(self, buf)
- }
-}
-
-impl<R: AsyncBufRead + ?Sized> AsyncBufReadExt for R {}
-
-pub async fn read_line<R: AsyncBufRead + Unpin + ?Sized>(
- r: &mut R,
- buf: &mut [u8],
-) -> Result<usize> {
- r.skip_while(|b| b == b'\r' || b == b'\n').await?;
- let n = r.read_while(buf, |b| b != b'\r' && b != b'\n').await?;
- r.skip_while(|b| b == b'\r').await?;
- //assert_eq!(b'\n', r.read_byte().await?);
- r.read_byte().await?;
- Ok(n)
-}
-
-pub trait AsyncWriteExt: AsyncWrite {
- fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAll<'a, Self>
- where
- Self: Unpin,
- {
- WriteAll::new(self, buf)
- }
-
- fn write_byte(&mut self, byte: u8) -> WriteByte<Self>
- where
- Self: Unpin,
- {
- WriteByte::new(self, byte)
- }
-
- fn write<'a>(&'a mut self, buf: &'a [u8]) -> Write<'a, Self>
- where
- Self: Unpin,
- {
- Write::new(self, buf)
- }
-
- /// Awaits until all bytes have actually been written, and
- /// not just enqueued as per the other "write" methods.
- fn flush<'a>(&mut self) -> Flush<Self>
- where
- Self: Unpin,
- {
- Flush::new(self)
- }
-}
-
-impl<R: AsyncWrite + ?Sized> AsyncWriteExt for R {}
diff --git a/embassy/src/io/util/read.rs b/embassy/src/io/util/read.rs
deleted file mode 100644
index 274b43a4..00000000
--- a/embassy/src/io/util/read.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use super::super::error::Result;
-use super::super::traits::AsyncBufRead;
-
-use core::cmp::min;
-
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-/// Future for the [`read_exact`](super::AsyncBufReadExt::read_exact) method.
-#[derive(Debug)]
-#[must_use = "futures do nothing unless you `.await` or poll them"]
-pub struct Read<'a, R: ?Sized> {
- reader: &'a mut R,
- buf: &'a mut [u8],
-}
-
-impl<R: ?Sized + Unpin> Unpin for Read<'_, R> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> Read<'a, R> {
- pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self {
- Read { reader, buf }
- }
-}
-
-impl<R: AsyncBufRead + ?Sized + Unpin> Future for Read<'_, R> {
- type Output = Result<usize>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let this = &mut *self;
- let buf = ready!(Pin::new(&mut this.reader).poll_fill_buf(cx))?;
-
- let n = min(this.buf.len(), buf.len());
- this.buf[..n].copy_from_slice(&buf[..n]);
- Pin::new(&mut this.reader).consume(n);
- Poll::Ready(Ok(n))
- }
-}
diff --git a/embassy/src/io/util/read_buf.rs b/embassy/src/io/util/read_buf.rs
deleted file mode 100644
index 71299b05..00000000
--- a/embassy/src/io/util/read_buf.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-use super::super::error::Result;
-use super::super::traits::AsyncBufRead;
-
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-pub struct ReadBuf<'a, R: ?Sized> {
- reader: Option<&'a mut R>,
-}
-
-impl<R: ?Sized + Unpin> Unpin for ReadBuf<'_, R> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadBuf<'a, R> {
- pub(super) fn new(reader: &'a mut R) -> Self {
- ReadBuf {
- reader: Some(reader),
- }
- }
-}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> Future for ReadBuf<'a, R> {
- type Output = Result<&'a [u8]>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let this = &mut *self;
-
- let buf = ready!(Pin::new(this.reader.as_mut().unwrap()).poll_fill_buf(cx))?;
- let buf: &'a [u8] = unsafe { core::mem::transmute(buf) };
- this.reader = None;
- Poll::Ready(Ok(buf))
- }
-}
diff --git a/embassy/src/io/util/read_byte.rs b/embassy/src/io/util/read_byte.rs
deleted file mode 100644
index e5bbcb1f..00000000
--- a/embassy/src/io/util/read_byte.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::{Error, Result};
-use super::super::traits::AsyncBufRead;
-
-pub struct ReadByte<'a, R: ?Sized> {
- reader: &'a mut R,
-}
-
-impl<R: ?Sized + Unpin> Unpin for ReadByte<'_, R> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadByte<'a, R> {
- pub(super) fn new(reader: &'a mut R) -> Self {
- Self { reader }
- }
-}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> Future for ReadByte<'a, R> {
- type Output = Result<u8>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let Self { reader } = &mut *self;
- let mut reader = Pin::new(reader);
- let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
- if rbuf.is_empty() {
- return Poll::Ready(Err(Error::UnexpectedEof));
- }
-
- let r = rbuf[0];
- reader.as_mut().consume(1);
- Poll::Ready(Ok(r))
- }
-}
diff --git a/embassy/src/io/util/read_exact.rs b/embassy/src/io/util/read_exact.rs
deleted file mode 100644
index 4eecba4c..00000000
--- a/embassy/src/io/util/read_exact.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use super::super::error::{Error, Result};
-use super::super::traits::AsyncBufRead;
-
-use core::cmp::min;
-use core::mem;
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-/// Future for the [`read_exact`](super::AsyncBufReadExt::read_exact) method.
-#[derive(Debug)]
-#[must_use = "futures do nothing unless you `.await` or poll them"]
-pub struct ReadExact<'a, R: ?Sized> {
- reader: &'a mut R,
- buf: &'a mut [u8],
-}
-
-impl<R: ?Sized + Unpin> Unpin for ReadExact<'_, R> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadExact<'a, R> {
- pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self {
- ReadExact { reader, buf }
- }
-}
-
-impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadExact<'_, R> {
- type Output = Result<()>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let this = &mut *self;
- while !this.buf.is_empty() {
- let buf = ready!(Pin::new(&mut this.reader).poll_fill_buf(cx))?;
- if buf.is_empty() {
- return Poll::Ready(Err(Error::UnexpectedEof));
- }
-
- let n = min(this.buf.len(), buf.len());
- this.buf[..n].copy_from_slice(&buf[..n]);
- Pin::new(&mut this.reader).consume(n);
- {
- let (_, rest) = mem::take(&mut this.buf).split_at_mut(n);
- this.buf = rest;
- }
- }
- Poll::Ready(Ok(()))
- }
-}
diff --git a/embassy/src/io/util/read_to_end.rs b/embassy/src/io/util/read_to_end.rs
deleted file mode 100644
index d09999ad..00000000
--- a/embassy/src/io/util/read_to_end.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use core::cmp::min;
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::{Error, Result};
-use super::super::traits::AsyncBufRead;
-
-pub struct ReadToEnd<'a, R: ?Sized> {
- reader: &'a mut R,
- buf: &'a mut [u8],
- n: usize,
-}
-
-impl<R: ?Sized + Unpin> Unpin for ReadToEnd<'_, R> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> ReadToEnd<'a, R> {
- pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self {
- Self { reader, buf, n: 0 }
- }
-}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin> Future for ReadToEnd<'a, R> {
- type Output = Result<usize>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let Self { reader, buf, n } = &mut *self;
- let mut reader = Pin::new(reader);
- loop {
- let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
- if rbuf.is_empty() {
- return Poll::Ready(Ok(*n));
- }
-
- if *n == buf.len() {
- return Poll::Ready(Err(Error::Truncated));
- }
-
- // truncate data if it doesn't fit in buf
- let p = min(rbuf.len(), buf.len() - *n);
- buf[*n..*n + p].copy_from_slice(&rbuf[..p]);
- *n += p;
-
- reader.as_mut().consume(p);
- }
- }
-}
diff --git a/embassy/src/io/util/read_while.rs b/embassy/src/io/util/read_while.rs
deleted file mode 100644
index e2463803..00000000
--- a/embassy/src/io/util/read_while.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-use core::cmp::min;
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::{Error, Result};
-use super::super::traits::AsyncBufRead;
-
-pub struct ReadWhile<'a, R: ?Sized, F> {
- reader: &'a mut R,
- buf: &'a mut [u8],
- n: usize,
- f: F,
-}
-
-impl<R: ?Sized + Unpin, F> Unpin for ReadWhile<'_, R, F> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin, F: Fn(u8) -> bool> ReadWhile<'a, R, F> {
- pub(super) fn new(reader: &'a mut R, f: F, buf: &'a mut [u8]) -> Self {
- Self {
- reader,
- f,
- buf,
- n: 0,
- }
- }
-}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin, F: Fn(u8) -> bool> Future for ReadWhile<'a, R, F> {
- type Output = Result<usize>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let Self { reader, f, buf, n } = &mut *self;
- let mut reader = Pin::new(reader);
- loop {
- let rbuf = ready!(reader.as_mut().poll_fill_buf(cx))?;
- if rbuf.is_empty() {
- return Poll::Ready(Err(Error::UnexpectedEof));
- }
-
- let (p, done) = match rbuf.iter().position(|&b| !f(b)) {
- Some(p) => (p, true),
- None => (rbuf.len(), false),
- };
-
- // truncate data if it doesn't fit in buf
- let p2 = min(p, buf.len() - *n);
- buf[*n..*n + p2].copy_from_slice(&rbuf[..p2]);
- *n += p2;
-
- // consume it all, even if it doesn't fit.
- // Otherwise we can deadlock because we never read to the ending char
- reader.as_mut().consume(p);
-
- if done {
- return Poll::Ready(Ok(*n));
- }
- }
- }
-}
diff --git a/embassy/src/io/util/skip_while.rs b/embassy/src/io/util/skip_while.rs
deleted file mode 100644
index 6f0e167d..00000000
--- a/embassy/src/io/util/skip_while.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use core::iter::Iterator;
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::{Error, Result};
-use super::super::traits::AsyncBufRead;
-
-pub struct SkipWhile<'a, R: ?Sized, F> {
- reader: &'a mut R,
- f: F,
-}
-
-impl<R: ?Sized + Unpin, F> Unpin for SkipWhile<'_, R, F> {}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin, F: Fn(u8) -> bool> SkipWhile<'a, R, F> {
- pub(super) fn new(reader: &'a mut R, f: F) -> Self {
- Self { reader, f }
- }
-}
-
-impl<'a, R: AsyncBufRead + ?Sized + Unpin, F: Fn(u8) -> bool> Future for SkipWhile<'a, R, F> {
- type Output = Result<()>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- let Self { reader, f } = &mut *self;
- let mut reader = Pin::new(reader);
- loop {
- let buf = ready!(reader.as_mut().poll_fill_buf(cx))?;
- if buf.is_empty() {
- return Poll::Ready(Err(Error::UnexpectedEof));
- }
-
- let (p, done) = match buf.iter().position(|b| !f(*b)) {
- Some(p) => (p, true),
- None => (buf.len(), false),
- };
- reader.as_mut().consume(p);
- if done {
- return Poll::Ready(Ok(()));
- }
- }
- }
-}
diff --git a/embassy/src/io/util/split.rs b/embassy/src/io/util/split.rs
deleted file mode 100644
index cc029aa5..00000000
--- a/embassy/src/io/util/split.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use alloc::rc::Rc;
-use core::cell::UnsafeCell;
-use core::pin::Pin;
-use futures::task::{Context, Poll};
-
-use super::super::error::Result;
-use super::super::traits::{AsyncBufRead, AsyncWrite};
-
-/// The readable half of an object returned from `AsyncBufRead::split`.
-#[derive(Debug)]
-pub struct ReadHalf<T> {
- handle: Rc<UnsafeCell<T>>,
-}
-
-/// The writable half of an object returned from `AsyncBufRead::split`.
-#[derive(Debug)]
-pub struct WriteHalf<T> {
- handle: Rc<UnsafeCell<T>>,
-}
-
-impl<T: AsyncBufRead + Unpin> AsyncBufRead for ReadHalf<T> {
- fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
- Pin::new(unsafe { &mut *self.handle.get() }).poll_fill_buf(cx)
- }
-
- fn consume(self: Pin<&mut Self>, amt: usize) {
- Pin::new(unsafe { &mut *self.handle.get() }).consume(amt)
- }
-}
-
-impl<T: AsyncWrite + Unpin> AsyncWrite for WriteHalf<T> {
- fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
- Pin::new(unsafe { &mut *self.handle.get() }).poll_write(cx, buf)
- }
- fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- Pin::new(unsafe { &mut *self.handle.get() }).poll_flush(cx)
- }
-}
-
-pub fn split<T: AsyncBufRead + AsyncWrite>(t: T) -> (ReadHalf<T>, WriteHalf<T>) {
- let c = Rc::new(UnsafeCell::new(t));
- (ReadHalf { handle: c.clone() }, WriteHalf { handle: c })
-}
diff --git a/embassy/src/io/util/write.rs b/embassy/src/io/util/write.rs
deleted file mode 100644
index 403cd59f..00000000
--- a/embassy/src/io/util/write.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::Result;
-use super::super::traits::AsyncWrite;
-
-/// Future for the [`write_all`](super::AsyncWriteExt::write_all) method.
-#[derive(Debug)]
-#[must_use = "futures do nothing unless you `.await` or poll them"]
-pub struct Write<'a, W: ?Sized> {
- writer: &'a mut W,
- buf: &'a [u8],
-}
-
-impl<W: ?Sized + Unpin> Unpin for Write<'_, W> {}
-
-impl<'a, W: AsyncWrite + ?Sized + Unpin> Write<'a, W> {
- pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self {
- Write { writer, buf }
- }
-}
-
-impl<W: AsyncWrite + ?Sized + Unpin> Future for Write<'_, W> {
- type Output = Result<usize>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<usize>> {
- let this = &mut *self;
- let n = ready!(Pin::new(&mut this.writer).poll_write(cx, this.buf))?;
- Poll::Ready(Ok(n))
- }
-}
diff --git a/embassy/src/io/util/write_all.rs b/embassy/src/io/util/write_all.rs
deleted file mode 100644
index 8a7d9984..00000000
--- a/embassy/src/io/util/write_all.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use core::mem;
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::Result;
-use super::super::traits::AsyncWrite;
-
-/// Future for the [`write_all`](super::AsyncWriteExt::write_all) method.
-#[derive(Debug)]
-#[must_use = "futures do nothing unless you `.await` or poll them"]
-pub struct WriteAll<'a, W: ?Sized> {
- writer: &'a mut W,
- buf: &'a [u8],
-}
-
-impl<W: ?Sized + Unpin> Unpin for WriteAll<'_, W> {}
-
-impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteAll<'a, W> {
- pub(super) fn new(writer: &'a mut W, buf: &'a [u8]) -> Self {
- WriteAll { writer, buf }
- }
-}
-
-impl<W: AsyncWrite + ?Sized + Unpin> Future for WriteAll<'_, W> {
- type Output = Result<()>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- let this = &mut *self;
- while !this.buf.is_empty() {
- let n = ready!(Pin::new(&mut this.writer).poll_write(cx, this.buf))?;
- {
- let (_, rest) = mem::take(&mut this.buf).split_at(n);
- this.buf = rest;
- }
- if n == 0 {
- panic!();
- }
- }
-
- Poll::Ready(Ok(()))
- }
-}
diff --git a/embassy/src/io/util/write_byte.rs b/embassy/src/io/util/write_byte.rs
deleted file mode 100644
index 659e427b..00000000
--- a/embassy/src/io/util/write_byte.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use core::pin::Pin;
-use futures::future::Future;
-use futures::ready;
-use futures::task::{Context, Poll};
-
-use super::super::error::Result;
-use super::super::traits::AsyncWrite;
-
-/// Future for the [`write_all`](super::AsyncWriteExt::write_all) method.
-#[derive(Debug)]
-#[must_use = "futures do nothing unless you `.await` or poll them"]
-pub struct WriteByte<'a, W: ?Sized> {
- writer: &'a mut W,
- byte: u8,
-}
-
-impl<W: ?Sized + Unpin> Unpin for WriteByte<'_, W> {}
-
-impl<'a, W: AsyncWrite + ?Sized + Unpin> WriteByte<'a, W> {
- pub(super) fn new(writer: &'a mut W, byte: u8) -> Self {
- WriteByte { writer, byte }
- }
-}
-
-impl<W: AsyncWrite + ?Sized + Unpin> Future for WriteByte<'_, W> {
- type Output = Result<()>;
-
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
- let this = &mut *self;
- let buf = [this.byte; 1];
- let n = ready!(Pin::new(&mut this.writer).poll_write(cx, &buf))?;
- if n == 0 {
- panic!();
- }
- assert!(n == 1);
-
- Poll::Ready(Ok(()))
- }
-}
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs
index ec697b40..087bd357 100644
--- a/embassy/src/lib.rs
+++ b/embassy/src/lib.rs
@@ -13,7 +13,6 @@ pub mod channel;
pub mod executor;
#[cfg(cortex_m)]
pub mod interrupt;
-pub mod io;
pub mod mutex;
#[cfg(feature = "time")]
pub mod time;
diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml
index 4258544f..ffac0a76 100644
--- a/examples/nrf/Cargo.toml
+++ b/examples/nrf/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.1.0"
[features]
default = ["nightly"]
-nightly = ["embassy-nrf/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embassy-usb-serial", "embassy-usb-hid", "embassy-usb-ncm"]
+nightly = ["embassy-nrf/nightly", "embassy-nrf/unstable-traits", "embassy-usb", "embassy-usb-serial", "embassy-usb-hid", "embassy-usb-ncm", "embedded-io/async", "embassy-net/nightly"]
[dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] }
@@ -16,6 +16,7 @@ embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defm
embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"], optional = true }
embassy-usb-hid = { version = "0.1.0", path = "../../embassy-usb-hid", features = ["defmt"], optional = true }
embassy-usb-ncm = { version = "0.1.0", path = "../../embassy-usb-ncm", features = ["defmt"], optional = true }
+embedded-io = "0.2.0"
defmt = "0.3"
defmt-rtt = "0.3"
diff --git a/examples/nrf/src/bin/buffered_uart.rs b/examples/nrf/src/bin/buffered_uart.rs
index 2cd163a9..a64c5821 100644
--- a/examples/nrf/src/bin/buffered_uart.rs
+++ b/examples/nrf/src/bin/buffered_uart.rs
@@ -4,9 +4,9 @@
use defmt::*;
use embassy::executor::Spawner;
-use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
use embassy_nrf::buffered_uarte::State;
use embassy_nrf::{buffered_uarte::BufferedUarte, interrupt, uarte, Peripherals};
+use embedded_io::asynch::{Read, Write};
use futures::pin_mut;
use defmt_rtt as _; // global logger
diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs
index f14a29c4..843487c0 100644
--- a/examples/nrf/src/bin/usb_ethernet.rs
+++ b/examples/nrf/src/bin/usb_ethernet.rs
@@ -10,9 +10,9 @@ use defmt::*;
use embassy::blocking_mutex::raw::ThreadModeRawMutex;
use embassy::channel::Channel;
use embassy::executor::Spawner;
-use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
use embassy::util::Forever;
-use embassy_net::{PacketBox, PacketBoxExt, PacketBuf, TcpSocket};
+use embassy_net::tcp::TcpSocket;
+use embassy_net::{PacketBox, PacketBoxExt, PacketBuf};
use embassy_nrf::pac;
use embassy_nrf::usb::Driver;
use embassy_nrf::Peripherals;
@@ -20,7 +20,9 @@ use embassy_nrf::{interrupt, peripherals};
use embassy_usb::{Builder, Config, UsbDevice};
use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State};
-use defmt_rtt as _; // global logger
+use defmt_rtt as _;
+use embedded_io::asynch::{Read, Write};
+// global logger
use panic_probe as _;
type MyDriver = Driver<'static, peripherals::USBD>;
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml
index 0853c323..fa2a98a4 100644
--- a/examples/std/Cargo.toml
+++ b/examples/std/Cargo.toml
@@ -6,7 +6,8 @@ version = "0.1.0"
[dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["log", "std", "time", "nightly"] }
-embassy-net = { version = "0.1.0", path = "../../embassy-net", features=["std", "log", "medium-ethernet", "tcp", "dhcpv4", "pool-16"] }
+embassy-net = { version = "0.1.0", path = "../../embassy-net", features=["nightly", "std", "log", "medium-ethernet", "tcp", "dhcpv4", "pool-16"] }
+embedded-io = { version = "0.2.0", features = ["async", "std"] }
async-io = "1.6.0"
env_logger = "0.9.0"
diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs
index 3b4bc6fe..daedffb0 100644
--- a/examples/std/src/bin/net.rs
+++ b/examples/std/src/bin/net.rs
@@ -2,12 +2,13 @@
use clap::Parser;
use embassy::executor::{Executor, Spawner};
-use embassy::io::AsyncWriteExt;
use embassy::util::Forever;
+use embassy_net::tcp::TcpSocket;
use embassy_net::{
Config, Configurator, DhcpConfigurator, Ipv4Address, Ipv4Cidr, StackResources,
- StaticConfigurator, TcpSocket,
+ StaticConfigurator,
};
+use embedded_io::asynch::Write;
use heapless::Vec;
use log::*;
diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs
index 129dc209..b1e5b014 100644
--- a/examples/std/src/bin/serial.rs
+++ b/examples/std/src/bin/serial.rs
@@ -5,8 +5,8 @@ mod serial_port;
use async_io::Async;
use embassy::executor::Executor;
-use embassy::io::AsyncBufReadExt;
use embassy::util::Forever;
+use embedded_io::asynch::Read;
use log::*;
use nix::sys::termios;
@@ -24,12 +24,12 @@ async fn run() {
// Essentially, async_io::Async converts from AsRawFd+Read+Write to futures's AsyncRead+AsyncWrite
let port = Async::new(port).unwrap();
- // This implements futures's AsyncBufRead based on futures's AsyncRead
- let port = futures::io::BufReader::new(port);
-
- // We can then use FromStdIo to convert from futures's AsyncBufRead+AsyncWrite
- // to embassy's AsyncBufRead+AsyncWrite
- let mut port = embassy::io::FromStdIo::new(port);
+ // We can then use FromStdIo to convert from futures's AsyncRead+AsyncWrite
+ // to embedded_io's async Read+Write.
+ //
+ // This is not really needed, you could write the code below using futures::io directly.
+ // It's useful if you want to have portable code across embedded and std.
+ let mut port = embedded_io::adapters::FromFutures::new(port);
info!("Serial opened!");
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml
index 09a06aa7..bbeee179 100644
--- a/examples/stm32f7/Cargo.toml
+++ b/examples/stm32f7/Cargo.toml
@@ -9,6 +9,7 @@ resolver = "2"
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] }
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", "tcp", "medium-ethernet", "pool-16"] }
+embedded-io = { version = "0.2.0", features = ["async"] }
defmt = "0.3"
defmt-rtt = "0.3"
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index 33e41de9..dca9338b 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -5,12 +5,10 @@
use cortex_m_rt::entry;
use defmt::*;
use embassy::executor::{Executor, Spawner};
-use embassy::io::AsyncWriteExt;
use embassy::time::{Duration, Timer};
use embassy::util::Forever;
-use embassy_net::{
- Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
-};
+use embassy_net::tcp::TcpSocket;
+use embassy_net::{Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator};
use embassy_stm32::eth::generic_smi::GenericSMI;
use embassy_stm32::eth::{Ethernet, State};
use embassy_stm32::interrupt;
@@ -19,6 +17,7 @@ use embassy_stm32::peripherals::RNG;
use embassy_stm32::rng::Rng;
use embassy_stm32::time::U32Ext;
use embassy_stm32::Config;
+use embedded_io::asynch::Write;
use heapless::Vec;
use defmt_rtt as _; // global logger
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 419bbec3..ff70e6db 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -5,12 +5,11 @@ name = "embassy-stm32h7-examples"
version = "0.1.0"
resolver = "2"
-[features]
-
[dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits"] }
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", "tcp", "medium-ethernet", "pool-16"] }
+embedded-io = { version = "0.2.0", features = ["async"] }
defmt = "0.3"
defmt-rtt = "0.3"
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index 9a2e7a33..8ece2940 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -8,12 +8,10 @@ use panic_probe as _;
use cortex_m_rt::entry;
use defmt::*;
use embassy::executor::{Executor, Spawner};
-use embassy::io::AsyncWriteExt;
use embassy::time::{Duration, Timer};
use embassy::util::Forever;
-use embassy_net::{
- Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
-};
+use embassy_net::tcp::TcpSocket;
+use embassy_net::{Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator};
use embassy_stm32::eth::generic_smi::GenericSMI;
use embassy_stm32::eth::{Ethernet, State};
use embassy_stm32::interrupt;
@@ -22,6 +20,7 @@ use embassy_stm32::peripherals::RNG;
use embassy_stm32::rng::Rng;
use embassy_stm32::time::U32Ext;
use embassy_stm32::Config;
+use embedded_io::asynch::Write;
use heapless::Vec;
#[embassy::task]
diff --git a/examples/stm32l0/.cargo/config.toml b/examples/stm32l0/.cargo/config.toml
index 840faa62..ec0b931f 100644
--- a/examples/stm32l0/.cargo/config.toml
+++ b/examples/stm32l0/.cargo/config.toml
@@ -1,6 +1,6 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# replace your chip as listed in `probe-run --list-chips`
-runner = "probe-run --chip STM32L072CZTx"
+runner = "probe-run --chip STM32L053R8Tx"
[build]
target = "thumbv6m-none-eabi"
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml
index 1cdb2f37..d6848c27 100644
--- a/examples/stm32l0/Cargo.toml
+++ b/examples/stm32l0/Cargo.toml
@@ -7,12 +7,11 @@ resolver = "2"
[features]
default = ["nightly"]
-nightly = ["embassy-stm32/nightly", "embassy-lora", "lorawan-device", "lorawan"]
+nightly = ["embassy-stm32/nightly", "embassy-lora", "lorawan-device", "lorawan", "embedded-io/async"]
[dependencies]
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt", "defmt-timestamp-uptime"] }
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] }
-
embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"], optional = true}
lorawan-device = { version = "0.7.1", default-features = false, features = ["async"], optional = true }
@@ -22,6 +21,7 @@ defmt = "0.3"
defmt-rtt = "0.3"
embedded-storage = "0.3.0"
+embedded-io = "0.2.0"
cortex-m = "0.7.3"
cortex-m-rt = "0.7.0"
diff --git a/examples/stm32l0/src/bin/usart_irq.rs b/examples/stm32l0/src/bin/usart_irq.rs
index abb27fa4..4413a294 100644
--- a/examples/stm32l0/src/bin/usart_irq.rs
+++ b/examples/stm32l0/src/bin/usart_irq.rs
@@ -2,13 +2,14 @@
#![no_main]
#![feature(type_alias_impl_trait)]
-use defmt_rtt as _; // global logger
+use defmt_rtt as _;
+use embedded_io::asynch::{Read, Write};
+// global logger
use panic_probe as _;
use defmt::*;
use embassy::executor::Spawner;
-use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
use embassy_stm32::dma::NoDma;
use embassy_stm32::interrupt;
use embassy_stm32::usart::{BufferedUart, Config, State, Uart};
@@ -16,19 +17,21 @@ use embassy_stm32::Peripherals;
#[embassy::main]
async fn main(_spawner: Spawner, p: Peripherals) {
+ info!("Hi!");
+
static mut TX_BUFFER: [u8; 8] = [0; 8];
static mut RX_BUFFER: [u8; 256] = [0; 256];
let mut config = Config::default();
config.baudrate = 9600;
- let usart = Uart::new(p.USART1, p.PA10, p.PA9, NoDma, NoDma, config);
+ let usart = Uart::new(p.USART2, p.PA3, p.PA2, NoDma, NoDma, config);
let mut state = State::new();
let mut usart = unsafe {
BufferedUart::new(
&mut state,
usart,
- interrupt::take!(USART1),
+ interrupt::take!(USART2),
&mut TX_BUFFER,
&mut RX_BUFFER,
)