Support unstable-trait feature for stm32
This commit is contained in:
@ -9,14 +9,16 @@ resolver = "2"
|
||||
embassy = { version = "0.1.0", path = "../embassy" }
|
||||
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] }
|
||||
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
|
||||
embassy-traits = {version = "0.1.0", path = "../embassy-traits" }
|
||||
embassy-net = { version = "0.1.0", path = "../embassy-net", default-features = false, optional = true }
|
||||
|
||||
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6" }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true}
|
||||
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy", optional = true}
|
||||
|
||||
defmt = { version = "0.3", optional = true }
|
||||
log = { version = "0.4.14", optional = true }
|
||||
cortex-m-rt = ">=0.6.15,<0.8"
|
||||
cortex-m = "0.7.3"
|
||||
embedded-hal = { version = "0.2.6", features = ["unproven"] }
|
||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||
rand_core = "0.6.3"
|
||||
sdio-host = "0.5.0"
|
||||
@ -56,6 +58,9 @@ time-driver-tim5 = ["_time-driver"]
|
||||
# There are no plans to make this stable.
|
||||
unstable-pac = []
|
||||
|
||||
# Implement embedded-hal 1.0 alpha and embedded-hal-async traits.
|
||||
unstable-traits = ["embedded-hal-1", "embedded-hal-async"]
|
||||
|
||||
# BEGIN GENERATED FEATURES
|
||||
# Generated by stm32-gen-features. DO NOT EDIT.
|
||||
stm32f030c6 = [ "stm32-metapac/stm32f030c6" ]
|
||||
|
@ -4,7 +4,7 @@ use crate::time::Hertz;
|
||||
use core::marker::PhantomData;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embedded_hal::blocking::delay::DelayUs;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
pub const VDDA_CALIB_MV: u32 = 3300;
|
||||
pub const ADC_MAX: u32 = (1 << 12) - 1;
|
||||
|
@ -2,7 +2,7 @@ use crate::adc::{AdcPin, Instance};
|
||||
use core::marker::PhantomData;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embedded_hal::blocking::delay::DelayUs;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
pub const VDDA_CALIB_MV: u32 = 3000;
|
||||
|
||||
|
@ -1,15 +1,10 @@
|
||||
use core::convert::Infallible;
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::pin::Pin;
|
||||
use core::task::{Context, Poll};
|
||||
use embassy::traits::gpio::{
|
||||
WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge,
|
||||
};
|
||||
use embassy::util::Unborrow;
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::unsafe_impl_unborrow;
|
||||
use embedded_hal::digital::v2::InputPin;
|
||||
|
||||
use crate::gpio::{AnyPin, Input, Pin as GpioPin};
|
||||
use crate::interrupt;
|
||||
@ -134,70 +129,88 @@ impl<'d, T: GpioPin> ExtiInput<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
|
||||
type Error = Infallible;
|
||||
mod eh02 {
|
||||
use super::*;
|
||||
use core::convert::Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_high())
|
||||
}
|
||||
impl<'d, T: GpioPin> embedded_hal_02::digital::v2::InputPin for ExtiInput<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_low())
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_high())
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_low())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> WaitForHigh for ExtiInput<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + 'a;
|
||||
#[cfg(feature = "unstable-traits")]
|
||||
mod eh1 {
|
||||
use super::*;
|
||||
use core::convert::Infallible;
|
||||
use futures::FutureExt;
|
||||
|
||||
fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.wait_for_high()
|
||||
impl<'d, T: GpioPin> embedded_hal_1::digital::ErrorType for ExtiInput<'d, T> {
|
||||
type Error = Infallible;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> WaitForLow for ExtiInput<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + 'a;
|
||||
impl<'d, T: GpioPin> embedded_hal_1::digital::blocking::InputPin for ExtiInput<'d, T> {
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_high())
|
||||
}
|
||||
|
||||
fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.wait_for_low()
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_low())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + 'a;
|
||||
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> {
|
||||
type WaitForHighFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.wait_for_rising_edge()
|
||||
}
|
||||
}
|
||||
fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
|
||||
self.wait_for_high().map(Ok)
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + 'a;
|
||||
type WaitForLowFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.wait_for_falling_edge()
|
||||
}
|
||||
}
|
||||
fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
|
||||
self.wait_for_low().map(Ok)
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> {
|
||||
type Future<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = ()> + 'a;
|
||||
type WaitForRisingEdgeFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
||||
self.wait_for_any_edge()
|
||||
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
|
||||
self.wait_for_rising_edge().map(Ok)
|
||||
}
|
||||
|
||||
type WaitForFallingEdgeFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
|
||||
self.wait_for_falling_edge().map(Ok)
|
||||
}
|
||||
|
||||
type WaitForAnyEdgeFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
|
||||
self.wait_for_any_edge().map(Ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ use core::convert::Infallible;
|
||||
use core::marker::PhantomData;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
||||
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
|
||||
use embedded_hal_02::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
|
||||
|
||||
use crate::pac;
|
||||
use crate::pac::gpio::{self, vals};
|
||||
|
@ -8,6 +8,7 @@ mod _version;
|
||||
use crate::{dma, peripherals};
|
||||
pub use _version::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Error {
|
||||
Bus,
|
||||
|
@ -270,7 +270,7 @@ impl<'d, T: Instance> I2c<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> {
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
|
||||
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||
@ -278,7 +278,7 @@ impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> {
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
|
||||
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||
@ -286,7 +286,7 @@ impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> {
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
|
||||
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||
|
@ -1,11 +1,9 @@
|
||||
use core::cmp;
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use atomic_polyfill::{AtomicUsize, Ordering};
|
||||
use embassy::interrupt::InterruptExt;
|
||||
use embassy::traits::i2c::I2c as I2cTrait;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy::waitqueue::AtomicWaker;
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
@ -735,32 +733,36 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
mod eh02 {
|
||||
use super::*;
|
||||
|
||||
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||
self.blocking_read(address, buffer)
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
|
||||
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||
self.blocking_read(address, buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::i2c::Write for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Write for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
|
||||
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||
self.blocking_write(address, bytes)
|
||||
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||
self.blocking_write(address, bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T> {
|
||||
type Error = Error;
|
||||
|
||||
fn write_read(
|
||||
&mut self,
|
||||
address: u8,
|
||||
bytes: &[u8],
|
||||
buffer: &mut [u8],
|
||||
) -> Result<(), Self::Error> {
|
||||
self.blocking_write_read(address, bytes, buffer)
|
||||
fn write_read(
|
||||
&mut self,
|
||||
address: u8,
|
||||
bytes: &[u8],
|
||||
buffer: &mut [u8],
|
||||
) -> Result<(), Self::Error> {
|
||||
self.blocking_write_read(address, bytes, buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -906,38 +908,80 @@ impl Timings {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TXDMA: super::TxDma<T>, RXDMA: super::RxDma<T>> I2cTrait<u8>
|
||||
for I2c<'d, T, TXDMA, RXDMA>
|
||||
{
|
||||
type Error = super::Error;
|
||||
#[cfg(feature = "unstable-traits")]
|
||||
mod eh1 {
|
||||
use super::super::{RxDma, TxDma};
|
||||
use super::*;
|
||||
use core::future::Future;
|
||||
|
||||
type WriteFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
type ReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
type WriteReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
self.read(address, buffer)
|
||||
impl embedded_hal_1::i2c::Error for Error {
|
||||
fn kind(&self) -> embedded_hal_1::i2c::ErrorKind {
|
||||
match *self {
|
||||
Self::Bus => embedded_hal_1::i2c::ErrorKind::Bus,
|
||||
Self::Arbitration => embedded_hal_1::i2c::ErrorKind::ArbitrationLoss,
|
||||
Self::Nack => embedded_hal_1::i2c::ErrorKind::NoAcknowledge(
|
||||
embedded_hal_1::i2c::NoAcknowledgeSource::Unknown,
|
||||
),
|
||||
Self::Timeout => embedded_hal_1::i2c::ErrorKind::Other,
|
||||
Self::Crc => embedded_hal_1::i2c::ErrorKind::Other,
|
||||
Self::Overrun => embedded_hal_1::i2c::ErrorKind::Overrun,
|
||||
Self::ZeroLengthTransfer => embedded_hal_1::i2c::ErrorKind::Other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.write(address, bytes)
|
||||
impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_1::i2c::ErrorType
|
||||
for I2c<'d, T, TXDMA, RXDMA>
|
||||
{
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
fn write_read<'a>(
|
||||
&'a mut self,
|
||||
address: u8,
|
||||
bytes: &'a [u8],
|
||||
buffer: &'a mut [u8],
|
||||
) -> Self::WriteReadFuture<'a> {
|
||||
self.write_read(address, bytes, buffer)
|
||||
impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c
|
||||
for I2c<'d, T, TXDMA, RXDMA>
|
||||
{
|
||||
type ReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
self.read(address, buffer)
|
||||
}
|
||||
|
||||
type WriteFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.write(address, bytes)
|
||||
}
|
||||
|
||||
type WriteReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
fn write_read<'a>(
|
||||
&'a mut self,
|
||||
address: u8,
|
||||
bytes: &'a [u8],
|
||||
buffer: &'a mut [u8],
|
||||
) -> Self::WriteReadFuture<'a> {
|
||||
self.write_read(address, bytes, buffer)
|
||||
}
|
||||
|
||||
type TransactionFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn transaction<'a>(
|
||||
&'a mut self,
|
||||
address: u8,
|
||||
operations: &mut [embedded_hal_async::i2c::Operation<'a>],
|
||||
) -> Self::TransactionFuture<'a> {
|
||||
let _ = address;
|
||||
let _ = operations;
|
||||
async move { todo!() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::unborrow;
|
||||
use embassy_traits::spi as traits;
|
||||
|
||||
use self::sealed::WordSize;
|
||||
use crate::dma;
|
||||
@ -17,7 +15,7 @@ use crate::peripherals;
|
||||
use crate::rcc::RccPeripheral;
|
||||
use crate::time::Hertz;
|
||||
|
||||
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||
|
||||
#[cfg_attr(spi_v1, path = "v1.rs")]
|
||||
#[cfg_attr(spi_f1, path = "v1.rs")]
|
||||
@ -549,76 +547,168 @@ fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> {
|
||||
return Ok(rx_word);
|
||||
}
|
||||
|
||||
// Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with
|
||||
// some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289
|
||||
macro_rules! impl_blocking {
|
||||
($w:ident) => {
|
||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Write<$w> for Spi<'d, T, NoDma, NoDma> {
|
||||
type Error = Error;
|
||||
mod eh02 {
|
||||
use super::*;
|
||||
|
||||
fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
|
||||
self.blocking_write(words)
|
||||
// Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with
|
||||
// some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289
|
||||
macro_rules! impl_blocking {
|
||||
($w:ident) => {
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::spi::Write<$w>
|
||||
for Spi<'d, T, NoDma, NoDma>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
|
||||
self.blocking_write(words)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::spi::Transfer<$w>
|
||||
for Spi<'d, T, NoDma, NoDma>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> {
|
||||
self.blocking_transfer_in_place(words)?;
|
||||
Ok(words)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_blocking!(u8);
|
||||
impl_blocking!(u16);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-traits")]
|
||||
mod eh1 {
|
||||
use super::*;
|
||||
use core::future::Future;
|
||||
|
||||
impl<'d, T: Instance, Tx, Rx> embedded_hal_1::spi::ErrorType for Spi<'d, T, Tx, Rx> {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl embedded_hal_1::spi::Error for Error {
|
||||
fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
|
||||
match *self {
|
||||
Self::Framing => embedded_hal_1::spi::ErrorKind::FrameFormat,
|
||||
Self::Crc => embedded_hal_1::spi::ErrorKind::Other,
|
||||
Self::ModeFault => embedded_hal_1::spi::ErrorKind::ModeFault,
|
||||
Self::Overrun => embedded_hal_1::spi::ErrorKind::Overrun,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<$w>
|
||||
for Spi<'d, T, NoDma, NoDma>
|
||||
{
|
||||
type Error = Error;
|
||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> embedded_hal_async::spi::Write<u8>
|
||||
for Spi<'d, T, Tx, Rx>
|
||||
{
|
||||
type WriteFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> {
|
||||
self.blocking_transfer_in_place(words)?;
|
||||
Ok(words)
|
||||
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.write(data)
|
||||
}
|
||||
|
||||
type WriteTransactionFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn write_transaction<'a>(
|
||||
&'a mut self,
|
||||
words: &'a [&'a [u8]],
|
||||
) -> Self::WriteTransactionFuture<'a> {
|
||||
async move {
|
||||
for buf in words {
|
||||
self.write(buf).await?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_blocking!(u8);
|
||||
impl_blocking!(u16);
|
||||
|
||||
impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> traits::Write<u8> for Spi<'d, T, Tx, Rx> {
|
||||
type WriteFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.write(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::Read<u8>
|
||||
for Spi<'d, T, Tx, Rx>
|
||||
{
|
||||
type ReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>>
|
||||
embedded_hal_async::spi::Read<u8> for Spi<'d, T, Tx, Rx>
|
||||
{
|
||||
type ReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
self.read(data)
|
||||
fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
self.read(data)
|
||||
}
|
||||
|
||||
type ReadTransactionFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn read_transaction<'a>(
|
||||
&'a mut self,
|
||||
words: &'a mut [&'a mut [u8]],
|
||||
) -> Self::ReadTransactionFuture<'a> {
|
||||
async move {
|
||||
for buf in words {
|
||||
self.read(buf).await?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::FullDuplex<u8>
|
||||
for Spi<'d, T, Tx, Rx>
|
||||
{
|
||||
type WriteReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>>
|
||||
embedded_hal_async::spi::ReadWrite<u8> for Spi<'d, T, Tx, Rx>
|
||||
{
|
||||
type TransferFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn read_write<'a>(
|
||||
&'a mut self,
|
||||
read: &'a mut [u8],
|
||||
write: &'a [u8],
|
||||
) -> Self::WriteReadFuture<'a> {
|
||||
self.transfer(read, write)
|
||||
fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> {
|
||||
self.transfer(rx, tx)
|
||||
}
|
||||
|
||||
type TransferInPlaceFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn transfer_in_place<'a>(
|
||||
&'a mut self,
|
||||
words: &'a mut [u8],
|
||||
) -> Self::TransferInPlaceFuture<'a> {
|
||||
// TODO: Implement async version
|
||||
let result = self.blocking_transfer_in_place(words);
|
||||
async move { result }
|
||||
}
|
||||
|
||||
type TransactionFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn transaction<'a>(
|
||||
&'a mut self,
|
||||
operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
|
||||
) -> Self::TransactionFuture<'a> {
|
||||
use embedded_hal_1::spi::blocking::Operation;
|
||||
async move {
|
||||
for o in operations {
|
||||
match o {
|
||||
Operation::Read(b) => self.read(b).await?,
|
||||
Operation::Write(b) => self.write(b).await?,
|
||||
Operation::Transfer(r, w) => self.transfer(r, w).await?,
|
||||
Operation::TransferInPlace(b) => self.transfer_in_place(b).await?,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
#![macro_use]
|
||||
|
||||
use core::future::Future;
|
||||
use core::marker::PhantomData;
|
||||
use embassy::interrupt::Interrupt;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::unborrow;
|
||||
use futures::TryFutureExt;
|
||||
|
||||
use crate::dma::NoDma;
|
||||
use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
|
||||
@ -211,72 +209,108 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal::serial::Read<u8> for Uart<'d, T, TxDma, RxDma> {
|
||||
type Error = Error;
|
||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||
let r = self.inner.regs();
|
||||
unsafe {
|
||||
let sr = sr(r).read();
|
||||
if sr.pe() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Parity))
|
||||
} else if sr.fe() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Framing))
|
||||
} else if sr.ne() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Noise))
|
||||
} else if sr.ore() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Overrun))
|
||||
} else if sr.rxne() {
|
||||
Ok(rdr(r).read_volatile())
|
||||
} else {
|
||||
Err(nb::Error::WouldBlock)
|
||||
mod eh02 {
|
||||
use super::*;
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::serial::Read<u8>
|
||||
for Uart<'d, T, TxDma, RxDma>
|
||||
{
|
||||
type Error = Error;
|
||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||
let r = self.inner.regs();
|
||||
unsafe {
|
||||
let sr = sr(r).read();
|
||||
if sr.pe() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Parity))
|
||||
} else if sr.fe() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Framing))
|
||||
} else if sr.ne() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Noise))
|
||||
} else if sr.ore() {
|
||||
rdr(r).read_volatile();
|
||||
Err(nb::Error::Other(Error::Overrun))
|
||||
} else if sr.rxne() {
|
||||
Ok(rdr(r).read_volatile())
|
||||
} else {
|
||||
Err(nb::Error::WouldBlock)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8>
|
||||
for Uart<'d, T, TxDma, RxDma>
|
||||
{
|
||||
type Error = Error;
|
||||
fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
|
||||
self.blocking_write(buffer)
|
||||
}
|
||||
fn bflush(&mut self) -> Result<(), Self::Error> {
|
||||
self.blocking_flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal::blocking::serial::Write<u8>
|
||||
for Uart<'d, T, TxDma, RxDma>
|
||||
{
|
||||
type Error = Error;
|
||||
fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
|
||||
self.blocking_write(buffer)
|
||||
}
|
||||
fn bflush(&mut self) -> Result<(), Self::Error> {
|
||||
self.blocking_flush()
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "unstable-traits")]
|
||||
mod eh1 {
|
||||
use super::*;
|
||||
use core::future::Future;
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, TxDma, RxDma>
|
||||
where
|
||||
TxDma: crate::usart::TxDma<T>,
|
||||
{
|
||||
type WriteFuture<'a>
|
||||
impl embedded_hal_1::serial::Error for Error {
|
||||
fn kind(&self) -> embedded_hal_1::serial::ErrorKind {
|
||||
match *self {
|
||||
Self::Framing => embedded_hal_1::serial::ErrorKind::FrameFormat,
|
||||
Self::Noise => embedded_hal_1::serial::ErrorKind::Noise,
|
||||
Self::Overrun => embedded_hal_1::serial::ErrorKind::Overrun,
|
||||
Self::Parity => embedded_hal_1::serial::ErrorKind::Parity,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_1::serial::ErrorType
|
||||
for Uart<'d, T, TxDma, RxDma>
|
||||
{
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Write for Uart<'d, T, TxDma, RxDma>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), embassy_traits::uart::Error>> + 'a;
|
||||
TxDma: crate::usart::TxDma<T>,
|
||||
{
|
||||
type WriteFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.write(buf)
|
||||
.map_err(|_| embassy_traits::uart::Error::Other)
|
||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||
self.write(buf)
|
||||
}
|
||||
|
||||
type FlushFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
|
||||
async move { Ok(()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Read for Uart<'d, T, TxDma, RxDma>
|
||||
where
|
||||
RxDma: crate::usart::RxDma<T>,
|
||||
{
|
||||
type ReadFuture<'a>
|
||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), embassy_traits::uart::Error>> + 'a;
|
||||
RxDma: crate::usart::RxDma<T>,
|
||||
{
|
||||
type ReadFuture<'a>
|
||||
where
|
||||
Self: 'a,
|
||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||
|
||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
self.read(buf)
|
||||
.map_err(|_| embassy_traits::uart::Error::Other)
|
||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||
self.read(buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user