Support unstable-trait feature for stm32
This commit is contained in:
parent
cd36e3f733
commit
4032fc0655
32 changed files with 604 additions and 673 deletions
|
@ -18,6 +18,8 @@ log = { version = "0.4.14", optional = true }
|
||||||
|
|
||||||
embassy = { version = "0.1.0", path = "../embassy", default-features = false }
|
embassy = { version = "0.1.0", path = "../embassy", default-features = false }
|
||||||
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
|
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
|
||||||
|
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.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"}
|
||||||
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
|
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
|
||||||
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
|
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
|
||||||
embedded-hal = { version = "0.2", features = ["unproven"] }
|
embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use embassy::traits::gpio::WaitForRisingEdge;
|
|
||||||
use embassy::traits::spi::*;
|
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
|
use embedded_hal_async::digital::Wait;
|
||||||
|
use embedded_hal_async::spi::*;
|
||||||
use lorawan_device::async_device::{
|
use lorawan_device::async_device::{
|
||||||
radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig},
|
radio::{Bandwidth, PhyRxTx, RfConfig, RxQuality, SpreadingFactor, TxConfig},
|
||||||
Timings,
|
Timings,
|
||||||
|
@ -20,11 +20,11 @@ pub trait RadioSwitch {
|
||||||
/// Semtech Sx127x radio peripheral
|
/// Semtech Sx127x radio peripheral
|
||||||
pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
pub struct Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
||||||
where
|
where
|
||||||
SPI: FullDuplex<u8, Error = E> + 'static,
|
SPI: ReadWrite<u8, Error = E> + 'static,
|
||||||
E: 'static,
|
E: 'static,
|
||||||
CS: OutputPin + 'static,
|
CS: OutputPin + 'static,
|
||||||
RESET: OutputPin + 'static,
|
RESET: OutputPin + 'static,
|
||||||
I: WaitForRisingEdge + 'static,
|
I: Wait + 'static,
|
||||||
RFS: RadioSwitch + 'static,
|
RFS: RadioSwitch + 'static,
|
||||||
{
|
{
|
||||||
radio: LoRa<SPI, CS, RESET>,
|
radio: LoRa<SPI, CS, RESET>,
|
||||||
|
@ -42,10 +42,10 @@ pub enum State {
|
||||||
|
|
||||||
impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
impl<SPI, CS, RESET, E, I, RFS> Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
||||||
where
|
where
|
||||||
SPI: FullDuplex<u8, Error = E> + 'static,
|
SPI: ReadWrite<u8, Error = E> + 'static,
|
||||||
CS: OutputPin + 'static,
|
CS: OutputPin + 'static,
|
||||||
RESET: OutputPin + 'static,
|
RESET: OutputPin + 'static,
|
||||||
I: WaitForRisingEdge + 'static,
|
I: Wait + 'static,
|
||||||
RFS: RadioSwitch + 'static,
|
RFS: RadioSwitch + 'static,
|
||||||
E: 'static,
|
E: 'static,
|
||||||
{
|
{
|
||||||
|
@ -64,10 +64,10 @@ where
|
||||||
|
|
||||||
impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
impl<SPI, CS, RESET, E, I, RFS> Timings for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
||||||
where
|
where
|
||||||
SPI: FullDuplex<u8, Error = E> + 'static,
|
SPI: ReadWrite<u8, Error = E> + 'static,
|
||||||
CS: OutputPin + 'static,
|
CS: OutputPin + 'static,
|
||||||
RESET: OutputPin + 'static,
|
RESET: OutputPin + 'static,
|
||||||
I: WaitForRisingEdge + 'static,
|
I: Wait + 'static,
|
||||||
RFS: RadioSwitch + 'static,
|
RFS: RadioSwitch + 'static,
|
||||||
{
|
{
|
||||||
fn get_rx_window_offset_ms(&self) -> i32 {
|
fn get_rx_window_offset_ms(&self) -> i32 {
|
||||||
|
@ -80,11 +80,11 @@ where
|
||||||
|
|
||||||
impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
impl<SPI, CS, RESET, E, I, RFS> PhyRxTx for Sx127xRadio<SPI, CS, RESET, E, I, RFS>
|
||||||
where
|
where
|
||||||
SPI: FullDuplex<u8, Error = E> + 'static,
|
SPI: ReadWrite<u8, Error = E> + 'static,
|
||||||
CS: OutputPin + 'static,
|
CS: OutputPin + 'static,
|
||||||
E: 'static,
|
E: 'static,
|
||||||
RESET: OutputPin + 'static,
|
RESET: OutputPin + 'static,
|
||||||
I: WaitForRisingEdge + 'static,
|
I: Wait + 'static,
|
||||||
RFS: RadioSwitch + 'static,
|
RFS: RadioSwitch + 'static,
|
||||||
{
|
{
|
||||||
type PhyError = Sx127xError;
|
type PhyError = Sx127xError;
|
||||||
|
@ -126,7 +126,7 @@ where
|
||||||
self.radio.transmit_start(buf).await?;
|
self.radio.transmit_start(buf).await?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
self.irq.wait_for_rising_edge().await;
|
self.irq.wait_for_rising_edge().await.unwrap();
|
||||||
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
|
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
|
||||||
let irq = self.radio.clear_irq().await.ok().unwrap();
|
let irq = self.radio.clear_irq().await.ok().unwrap();
|
||||||
if (irq & IRQ::IrqTxDoneMask.addr()) != 0 {
|
if (irq & IRQ::IrqTxDoneMask.addr()) != 0 {
|
||||||
|
@ -171,7 +171,7 @@ where
|
||||||
self.radio.set_mode(RadioMode::RxContinuous).await?;
|
self.radio.set_mode(RadioMode::RxContinuous).await?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
self.irq.wait_for_rising_edge().await;
|
self.irq.wait_for_rising_edge().await.unwrap();
|
||||||
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
|
self.radio.set_mode(RadioMode::Stdby).await.ok().unwrap();
|
||||||
let irq = self.radio.clear_irq().await.ok().unwrap();
|
let irq = self.radio.clear_irq().await.ok().unwrap();
|
||||||
if (irq & IRQ::IrqRxDoneMask.addr()) != 0 {
|
if (irq & IRQ::IrqRxDoneMask.addr()) != 0 {
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
use bit_field::BitField;
|
use bit_field::BitField;
|
||||||
use embassy::time::{Duration, Timer};
|
use embassy::time::{Duration, Timer};
|
||||||
use embassy::traits::spi::*;
|
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
|
use embedded_hal_async::spi::ReadWrite;
|
||||||
|
|
||||||
mod register;
|
mod register;
|
||||||
use self::register::PaConfig;
|
use self::register::PaConfig;
|
||||||
|
@ -36,9 +36,10 @@ pub enum Error<SPI, CS, RESET> {
|
||||||
Transmitting,
|
Transmitting,
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::sx127x_lora::register::{FskDataModulationShaping, FskRampUpRamDown};
|
|
||||||
use Error::*;
|
use Error::*;
|
||||||
|
|
||||||
|
use super::sx127x_lora::register::{FskDataModulationShaping, FskRampUpRamDown};
|
||||||
|
|
||||||
#[cfg(not(feature = "version_0x09"))]
|
#[cfg(not(feature = "version_0x09"))]
|
||||||
const VERSION_CHECK: u8 = 0x12;
|
const VERSION_CHECK: u8 = 0x12;
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ const VERSION_CHECK: u8 = 0x09;
|
||||||
|
|
||||||
impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET>
|
impl<SPI, CS, RESET, E> LoRa<SPI, CS, RESET>
|
||||||
where
|
where
|
||||||
SPI: FullDuplex<u8, Error = E>,
|
SPI: ReadWrite<u8, Error = E>,
|
||||||
CS: OutputPin,
|
CS: OutputPin,
|
||||||
RESET: OutputPin,
|
RESET: OutputPin,
|
||||||
{
|
{
|
||||||
|
@ -546,7 +547,7 @@ where
|
||||||
|
|
||||||
let _ = self
|
let _ = self
|
||||||
.spi
|
.spi
|
||||||
.read_write(&mut buffer, &[reg & 0x7f, 0])
|
.transfer(&mut buffer, &[reg & 0x7f, 0])
|
||||||
.await
|
.await
|
||||||
.map_err(SPI)?;
|
.map_err(SPI)?;
|
||||||
|
|
||||||
|
|
|
@ -9,14 +9,16 @@ resolver = "2"
|
||||||
embassy = { version = "0.1.0", path = "../embassy" }
|
embassy = { version = "0.1.0", path = "../embassy" }
|
||||||
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] }
|
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] }
|
||||||
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
|
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 }
|
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 }
|
defmt = { version = "0.3", optional = true }
|
||||||
log = { version = "0.4.14", optional = true }
|
log = { version = "0.4.14", optional = true }
|
||||||
cortex-m-rt = ">=0.6.15,<0.8"
|
cortex-m-rt = ">=0.6.15,<0.8"
|
||||||
cortex-m = "0.7.3"
|
cortex-m = "0.7.3"
|
||||||
embedded-hal = { version = "0.2.6", features = ["unproven"] }
|
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
rand_core = "0.6.3"
|
rand_core = "0.6.3"
|
||||||
sdio-host = "0.5.0"
|
sdio-host = "0.5.0"
|
||||||
|
@ -56,6 +58,9 @@ time-driver-tim5 = ["_time-driver"]
|
||||||
# There are no plans to make this stable.
|
# There are no plans to make this stable.
|
||||||
unstable-pac = []
|
unstable-pac = []
|
||||||
|
|
||||||
|
# Implement embedded-hal 1.0 alpha and embedded-hal-async traits.
|
||||||
|
unstable-traits = ["embedded-hal-1", "embedded-hal-async"]
|
||||||
|
|
||||||
# BEGIN GENERATED FEATURES
|
# BEGIN GENERATED FEATURES
|
||||||
# Generated by stm32-gen-features. DO NOT EDIT.
|
# Generated by stm32-gen-features. DO NOT EDIT.
|
||||||
stm32f030c6 = [ "stm32-metapac/stm32f030c6" ]
|
stm32f030c6 = [ "stm32-metapac/stm32f030c6" ]
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::time::Hertz;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy_hal_common::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 VDDA_CALIB_MV: u32 = 3300;
|
||||||
pub const ADC_MAX: u32 = (1 << 12) - 1;
|
pub const ADC_MAX: u32 = (1 << 12) - 1;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::adc::{AdcPin, Instance};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy_hal_common::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;
|
pub const VDDA_CALIB_MV: u32 = 3000;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
use core::convert::Infallible;
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
use embassy::traits::gpio::{
|
|
||||||
WaitForAnyEdge, WaitForFallingEdge, WaitForHigh, WaitForLow, WaitForRisingEdge,
|
|
||||||
};
|
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy::waitqueue::AtomicWaker;
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::unsafe_impl_unborrow;
|
use embassy_hal_common::unsafe_impl_unborrow;
|
||||||
use embedded_hal::digital::v2::InputPin;
|
|
||||||
|
|
||||||
use crate::gpio::{AnyPin, Input, Pin as GpioPin};
|
use crate::gpio::{AnyPin, Input, Pin as GpioPin};
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
|
@ -134,7 +129,11 @@ impl<'d, T: GpioPin> ExtiInput<'d, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
|
mod eh02 {
|
||||||
|
use super::*;
|
||||||
|
use core::convert::Infallible;
|
||||||
|
|
||||||
|
impl<'d, T: GpioPin> embedded_hal_02::digital::v2::InputPin for ExtiInput<'d, T> {
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||||
|
@ -145,59 +144,73 @@ impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
|
||||||
Ok(self.is_low())
|
Ok(self.is_low())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: GpioPin> WaitForHigh for ExtiInput<'d, T> {
|
#[cfg(feature = "unstable-traits")]
|
||||||
type Future<'a>
|
mod eh1 {
|
||||||
|
use super::*;
|
||||||
|
use core::convert::Infallible;
|
||||||
|
use futures::FutureExt;
|
||||||
|
|
||||||
|
impl<'d, T: GpioPin> embedded_hal_1::digital::ErrorType for ExtiInput<'d, T> {
|
||||||
|
type Error = Infallible;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 is_low(&self) -> Result<bool, Self::Error> {
|
||||||
|
Ok(self.is_low())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: GpioPin> embedded_hal_async::digital::Wait for ExtiInput<'d, T> {
|
||||||
|
type WaitForHighFuture<'a>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = ()> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn wait_for_high<'a>(&'a mut self) -> Self::Future<'a> {
|
fn wait_for_high<'a>(&'a mut self) -> Self::WaitForHighFuture<'a> {
|
||||||
self.wait_for_high()
|
self.wait_for_high().map(Ok)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GpioPin> WaitForLow for ExtiInput<'d, T> {
|
type WaitForLowFuture<'a>
|
||||||
type Future<'a>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = ()> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn wait_for_low<'a>(&'a mut self) -> Self::Future<'a> {
|
fn wait_for_low<'a>(&'a mut self) -> Self::WaitForLowFuture<'a> {
|
||||||
self.wait_for_low()
|
self.wait_for_low().map(Ok)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GpioPin> WaitForRisingEdge for ExtiInput<'d, T> {
|
type WaitForRisingEdgeFuture<'a>
|
||||||
type Future<'a>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = ()> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
fn wait_for_rising_edge<'a>(&'a mut self) -> Self::WaitForRisingEdgeFuture<'a> {
|
||||||
self.wait_for_rising_edge()
|
self.wait_for_rising_edge().map(Ok)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GpioPin> WaitForFallingEdge for ExtiInput<'d, T> {
|
type WaitForFallingEdgeFuture<'a>
|
||||||
type Future<'a>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = ()> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
fn wait_for_falling_edge<'a>(&'a mut self) -> Self::WaitForFallingEdgeFuture<'a> {
|
||||||
self.wait_for_falling_edge()
|
self.wait_for_falling_edge().map(Ok)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: GpioPin> WaitForAnyEdge for ExtiInput<'d, T> {
|
type WaitForAnyEdgeFuture<'a>
|
||||||
type Future<'a>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = ()> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn wait_for_any_edge<'a>(&'a mut self) -> Self::Future<'a> {
|
fn wait_for_any_edge<'a>(&'a mut self) -> Self::WaitForAnyEdgeFuture<'a> {
|
||||||
self.wait_for_any_edge()
|
self.wait_for_any_edge().map(Ok)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use core::convert::Infallible;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy_hal_common::{unborrow, unsafe_impl_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;
|
||||||
use crate::pac::gpio::{self, vals};
|
use crate::pac::gpio::{self, vals};
|
||||||
|
|
|
@ -8,6 +8,7 @@ mod _version;
|
||||||
use crate::{dma, peripherals};
|
use crate::{dma, peripherals};
|
||||||
pub use _version::*;
|
pub use _version::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Bus,
|
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;
|
type Error = Error;
|
||||||
|
|
||||||
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::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;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::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;
|
type Error = Error;
|
||||||
|
|
||||||
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::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::cmp;
|
||||||
use core::future::Future;
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use atomic_polyfill::{AtomicUsize, Ordering};
|
use atomic_polyfill::{AtomicUsize, Ordering};
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::traits::i2c::I2c as I2cTrait;
|
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy::waitqueue::AtomicWaker;
|
use embassy::waitqueue::AtomicWaker;
|
||||||
use embassy_hal_common::drop::OnDrop;
|
use embassy_hal_common::drop::OnDrop;
|
||||||
|
@ -735,7 +733,10 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal::blocking::i2c::Read for I2c<'d, T> {
|
mod eh02 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
|
||||||
|
@ -743,7 +744,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;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
|
||||||
|
@ -751,7 +752,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;
|
type Error = Error;
|
||||||
|
|
||||||
fn write_read(
|
fn write_read(
|
||||||
|
@ -763,6 +764,7 @@ impl<'d, T: Instance> embedded_hal::blocking::i2c::WriteRead for I2c<'d, T> {
|
||||||
self.blocking_write_read(address, bytes, buffer)
|
self.blocking_write_read(address, bytes, buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// I2C Stop Configuration
|
/// I2C Stop Configuration
|
||||||
///
|
///
|
||||||
|
@ -906,32 +908,58 @@ impl Timings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, TXDMA: super::TxDma<T>, RXDMA: super::RxDma<T>> I2cTrait<u8>
|
#[cfg(feature = "unstable-traits")]
|
||||||
|
mod eh1 {
|
||||||
|
use super::super::{RxDma, TxDma};
|
||||||
|
use super::*;
|
||||||
|
use core::future::Future;
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_1::i2c::ErrorType
|
||||||
for I2c<'d, T, TXDMA, RXDMA>
|
for I2c<'d, T, TXDMA, RXDMA>
|
||||||
{
|
{
|
||||||
type Error = super::Error;
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
type WriteFuture<'a>
|
impl<'d, T: Instance, TXDMA: TxDma<T>, RXDMA: RxDma<T>> embedded_hal_async::i2c::I2c
|
||||||
where
|
for I2c<'d, T, TXDMA, RXDMA>
|
||||||
Self: 'a,
|
{
|
||||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
|
||||||
type ReadFuture<'a>
|
type ReadFuture<'a>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = Result<(), Self::Error>> + '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> {
|
fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
self.read(address, buffer)
|
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> {
|
fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||||
self.write(address, bytes)
|
self.write(address, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WriteReadFuture<'a>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
fn write_read<'a>(
|
fn write_read<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
address: u8,
|
address: u8,
|
||||||
|
@ -940,4 +968,20 @@ impl<'d, T: Instance, TXDMA: super::TxDma<T>, RXDMA: super::RxDma<T>> I2cTrait<u
|
||||||
) -> Self::WriteReadFuture<'a> {
|
) -> Self::WriteReadFuture<'a> {
|
||||||
self.write_read(address, bytes, buffer)
|
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]
|
#![macro_use]
|
||||||
|
|
||||||
use core::future::Future;
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use embassy_traits::spi as traits;
|
|
||||||
|
|
||||||
use self::sealed::WordSize;
|
use self::sealed::WordSize;
|
||||||
use crate::dma;
|
use crate::dma;
|
||||||
|
@ -17,7 +15,7 @@ use crate::peripherals;
|
||||||
use crate::rcc::RccPeripheral;
|
use crate::rcc::RccPeripheral;
|
||||||
use crate::time::Hertz;
|
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_v1, path = "v1.rs")]
|
||||||
#[cfg_attr(spi_f1, path = "v1.rs")]
|
#[cfg_attr(spi_f1, path = "v1.rs")]
|
||||||
|
@ -549,11 +547,16 @@ fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> {
|
||||||
return Ok(rx_word);
|
return Ok(rx_word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod eh02 {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
// Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with
|
// 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
|
// some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289
|
||||||
macro_rules! impl_blocking {
|
macro_rules! impl_blocking {
|
||||||
($w:ident) => {
|
($w:ident) => {
|
||||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Write<$w> for Spi<'d, T, NoDma, NoDma> {
|
impl<'d, T: Instance> embedded_hal_02::blocking::spi::Write<$w>
|
||||||
|
for Spi<'d, T, NoDma, NoDma>
|
||||||
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
|
fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
|
||||||
|
@ -561,7 +564,7 @@ macro_rules! impl_blocking {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<$w>
|
impl<'d, T: Instance> embedded_hal_02::blocking::spi::Transfer<$w>
|
||||||
for Spi<'d, T, NoDma, NoDma>
|
for Spi<'d, T, NoDma, NoDma>
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
@ -576,12 +579,31 @@ macro_rules! impl_blocking {
|
||||||
|
|
||||||
impl_blocking!(u8);
|
impl_blocking!(u8);
|
||||||
impl_blocking!(u16);
|
impl_blocking!(u16);
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> {
|
#[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;
|
type Error = Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> traits::Write<u8> for Spi<'d, T, Tx, Rx> {
|
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, Tx: TxDmaChannel<T>, Rx> embedded_hal_async::spi::Write<u8>
|
||||||
|
for Spi<'d, T, Tx, Rx>
|
||||||
|
{
|
||||||
type WriteFuture<'a>
|
type WriteFuture<'a>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
|
@ -590,10 +612,27 @@ impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> traits::Write<u8> for Spi<'d, T,
|
||||||
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
|
fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||||
self.write(data)
|
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<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::Read<u8>
|
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>>
|
||||||
for Spi<'d, T, Tx, Rx>
|
embedded_hal_async::spi::Read<u8> for Spi<'d, T, Tx, Rx>
|
||||||
{
|
{
|
||||||
type ReadFuture<'a>
|
type ReadFuture<'a>
|
||||||
where
|
where
|
||||||
|
@ -603,22 +642,73 @@ impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::Read<u8>
|
||||||
fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
self.read(data)
|
self.read(data)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::FullDuplex<u8>
|
type ReadTransactionFuture<'a>
|
||||||
for Spi<'d, T, Tx, Rx>
|
|
||||||
{
|
|
||||||
type WriteReadFuture<'a>
|
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn read_write<'a>(
|
fn read_transaction<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
read: &'a mut [u8],
|
words: &'a mut [&'a mut [u8]],
|
||||||
write: &'a [u8],
|
) -> Self::ReadTransactionFuture<'a> {
|
||||||
) -> Self::WriteReadFuture<'a> {
|
async move {
|
||||||
self.transfer(read, write)
|
for buf in words {
|
||||||
|
self.read(buf).await?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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]
|
#![macro_use]
|
||||||
|
|
||||||
use core::future::Future;
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use embassy::interrupt::Interrupt;
|
use embassy::interrupt::Interrupt;
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use futures::TryFutureExt;
|
|
||||||
|
|
||||||
use crate::dma::NoDma;
|
use crate::dma::NoDma;
|
||||||
use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
|
use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
|
||||||
|
@ -211,7 +209,12 @@ 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> {
|
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;
|
type Error = Error;
|
||||||
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
|
||||||
let r = self.inner.regs();
|
let r = self.inner.regs();
|
||||||
|
@ -238,7 +241,7 @@ impl<'d, T: Instance, TxDma, RxDma> embedded_hal::serial::Read<u8> for Uart<'d,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, TxDma, RxDma> embedded_hal::blocking::serial::Write<u8>
|
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_02::blocking::serial::Write<u8>
|
||||||
for Uart<'d, T, TxDma, RxDma>
|
for Uart<'d, T, TxDma, RxDma>
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
@ -249,34 +252,65 @@ impl<'d, T: Instance, TxDma, RxDma> embedded_hal::blocking::serial::Write<u8>
|
||||||
self.blocking_flush()
|
self.blocking_flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, TxDma, RxDma> embassy_traits::uart::Write for Uart<'d, T, TxDma, RxDma>
|
#[cfg(feature = "unstable-traits")]
|
||||||
|
mod eh1 {
|
||||||
|
use super::*;
|
||||||
|
use core::future::Future;
|
||||||
|
|
||||||
|
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
|
where
|
||||||
TxDma: crate::usart::TxDma<T>,
|
TxDma: crate::usart::TxDma<T>,
|
||||||
{
|
{
|
||||||
type WriteFuture<'a>
|
type WriteFuture<'a>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = Result<(), embassy_traits::uart::Error>> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||||
self.write(buf)
|
self.write(buf)
|
||||||
.map_err(|_| embassy_traits::uart::Error::Other)
|
}
|
||||||
|
|
||||||
|
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>
|
impl<'d, T: Instance, TxDma, RxDma> embedded_hal_async::serial::Read for Uart<'d, T, TxDma, RxDma>
|
||||||
where
|
where
|
||||||
RxDma: crate::usart::RxDma<T>,
|
RxDma: crate::usart::RxDma<T>,
|
||||||
{
|
{
|
||||||
type ReadFuture<'a>
|
type ReadFuture<'a>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
= impl Future<Output = Result<(), embassy_traits::uart::Error>> + 'a;
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
self.read(buf)
|
self.read(buf)
|
||||||
.map_err(|_| embassy_traits::uart::Error::Other)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,7 @@ std = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
embedded-hal = { version = "0.2.6", features = ["unproven"] }
|
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
|
||||||
|
embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.6", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy" }
|
||||||
|
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
|
||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use embedded_hal::blocking;
|
use embedded_hal_02::blocking;
|
||||||
use embedded_hal::serial;
|
use embedded_hal_02::serial;
|
||||||
|
|
||||||
/// BlockingAsync is a wrapper that implements async traits using blocking peripherals. This allows
|
/// BlockingAsync is a wrapper that implements async traits using blocking peripherals. This allows
|
||||||
/// driver writers to depend on the async traits while still supporting embedded-hal peripheral implementations.
|
/// driver writers to depend on the async traits while still supporting embedded-hal peripheral implementations.
|
||||||
|
@ -20,24 +20,37 @@ impl<T> BlockingAsync<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// I2C implementatinos
|
// I2C implementations
|
||||||
//
|
//
|
||||||
|
impl<T, E> embedded_hal_1::i2c::ErrorType for BlockingAsync<T>
|
||||||
impl<T, E> crate::i2c::I2c for BlockingAsync<T>
|
|
||||||
where
|
where
|
||||||
E: 'static,
|
E: embedded_hal_1::i2c::Error + 'static,
|
||||||
T: blocking::i2c::WriteRead<Error = E>
|
T: blocking::i2c::WriteRead<Error = E>
|
||||||
+ blocking::i2c::Read<Error = E>
|
+ blocking::i2c::Read<Error = E>
|
||||||
+ blocking::i2c::Write<Error = E>,
|
+ blocking::i2c::Write<Error = E>,
|
||||||
{
|
{
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
impl<T, E> embedded_hal_async::i2c::I2c for BlockingAsync<T>
|
||||||
type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
|
where
|
||||||
#[rustfmt::skip]
|
E: embedded_hal_1::i2c::Error + 'static,
|
||||||
type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
|
T: blocking::i2c::WriteRead<Error = E>
|
||||||
#[rustfmt::skip]
|
+ blocking::i2c::Read<Error = E>
|
||||||
type WriteReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
|
+ blocking::i2c::Write<Error = E>,
|
||||||
|
{
|
||||||
|
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> {
|
fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
async move { self.wrapped.read(address, buffer) }
|
async move { self.wrapped.read(address, buffer) }
|
||||||
|
@ -55,33 +68,46 @@ where
|
||||||
) -> Self::WriteReadFuture<'a> {
|
) -> Self::WriteReadFuture<'a> {
|
||||||
async move { self.wrapped.write_read(address, bytes, buffer) }
|
async move { self.wrapped.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!() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// SPI implementatinos
|
// SPI implementatinos
|
||||||
//
|
//
|
||||||
|
|
||||||
impl<T, E, Word> crate::spi::Spi<Word> for BlockingAsync<T>
|
impl<T, E> embedded_hal_async::spi::ErrorType for BlockingAsync<T>
|
||||||
where
|
where
|
||||||
T: blocking::spi::Write<Word, Error = E>,
|
E: embedded_hal_1::spi::Error,
|
||||||
|
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
|
||||||
{
|
{
|
||||||
type Error = E;
|
type Error = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, E, Word> crate::spi::FullDuplex<Word> for BlockingAsync<T>
|
impl<T, E> embedded_hal_async::spi::ReadWrite<u8> for BlockingAsync<T>
|
||||||
where
|
where
|
||||||
E: 'static,
|
E: embedded_hal_1::spi::Error + 'static,
|
||||||
Word: Clone,
|
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
|
||||||
T: blocking::spi::Transfer<Word, Error = E> + blocking::spi::Write<Word, Error = E>,
|
|
||||||
{
|
{
|
||||||
#[rustfmt::skip]
|
type TransferFuture<'a>
|
||||||
type WriteReadFuture<'a> where Word: 'a, Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
|
where
|
||||||
|
Self: 'a,
|
||||||
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
fn read_write<'a>(
|
fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Self::TransferFuture<'a> {
|
||||||
&'a mut self,
|
|
||||||
read: &'a mut [Word],
|
|
||||||
write: &'a [Word],
|
|
||||||
) -> Self::WriteReadFuture<'a> {
|
|
||||||
async move {
|
async move {
|
||||||
// Ensure we write the expected bytes
|
// Ensure we write the expected bytes
|
||||||
for i in 0..core::cmp::min(read.len(), write.len()) {
|
for i in 0..core::cmp::min(read.len(), write.len()) {
|
||||||
|
@ -91,53 +117,111 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, E, Word> crate::spi::Write<Word> for BlockingAsync<T>
|
type TransferInPlaceFuture<'a>
|
||||||
where
|
where
|
||||||
E: 'static,
|
Self: 'a,
|
||||||
Word: Clone,
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
T: blocking::spi::Write<Word, Error = E>,
|
|
||||||
{
|
|
||||||
#[rustfmt::skip]
|
|
||||||
type WriteFuture<'a> where Word: 'a, Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
|
|
||||||
|
|
||||||
fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'a> {
|
fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Self::TransferInPlaceFuture<'a> {
|
||||||
async move { self.wrapped.write(data) }
|
async move { todo!() }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, E, Word> crate::spi::Read<Word> for BlockingAsync<T>
|
type TransactionFuture<'a>
|
||||||
where
|
where
|
||||||
E: 'static,
|
Self: 'a,
|
||||||
Word: Clone,
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
T: blocking::spi::Transfer<Word, Error = E> + blocking::spi::Write<Word, Error = E>,
|
|
||||||
{
|
|
||||||
#[rustfmt::skip]
|
|
||||||
type ReadFuture<'a> where Word: 'a, Self: 'a = impl Future<Output = Result<(), Self::Error>> + 'a;
|
|
||||||
|
|
||||||
fn read<'a>(&'a mut self, data: &'a mut [Word]) -> Self::ReadFuture<'a> {
|
fn transaction<'a>(
|
||||||
|
&'a mut self,
|
||||||
|
_: &'a mut [embedded_hal_async::spi::Operation<'a, u8>],
|
||||||
|
) -> Self::TransactionFuture<'a> {
|
||||||
|
async move { todo!() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> embedded_hal_async::spi::Write<u8> for BlockingAsync<T>
|
||||||
|
where
|
||||||
|
E: embedded_hal_1::spi::Error + 'static,
|
||||||
|
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
|
||||||
|
{
|
||||||
|
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> {
|
||||||
|
async move {
|
||||||
|
self.wrapped.write(data)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type WriteTransactionFuture<'a>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
|
fn write_transaction<'a>(&'a mut self, _: &'a [&'a [u8]]) -> Self::WriteTransactionFuture<'a> {
|
||||||
|
async move { todo!() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E> embedded_hal_async::spi::Read<u8> for BlockingAsync<T>
|
||||||
|
where
|
||||||
|
E: embedded_hal_1::spi::Error + 'static,
|
||||||
|
T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
|
||||||
|
{
|
||||||
|
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> {
|
||||||
async move {
|
async move {
|
||||||
self.wrapped.transfer(data)?;
|
self.wrapped.transfer(data)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReadTransactionFuture<'a>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
|
||||||
|
fn read_transaction<'a>(
|
||||||
|
&'a mut self,
|
||||||
|
_: &'a mut [&'a mut [u8]],
|
||||||
|
) -> Self::ReadTransactionFuture<'a> {
|
||||||
|
async move { todo!() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uart implementatinos
|
// Uart implementatinos
|
||||||
impl<T> crate::uart::Read for BlockingAsync<T>
|
impl<T, E> embedded_hal_1::serial::ErrorType for BlockingAsync<T>
|
||||||
where
|
where
|
||||||
T: serial::Read<u8>,
|
T: serial::Read<u8, Error = E>,
|
||||||
|
E: embedded_hal_1::serial::Error + 'static,
|
||||||
{
|
{
|
||||||
#[rustfmt::skip]
|
type Error = E;
|
||||||
type ReadFuture<'a> where T: 'a = impl Future<Output = Result<(), crate::uart::Error>> + 'a;
|
}
|
||||||
|
|
||||||
|
impl<T, E> embedded_hal_async::serial::Read for BlockingAsync<T>
|
||||||
|
where
|
||||||
|
T: serial::Read<u8, Error = E>,
|
||||||
|
E: embedded_hal_1::serial::Error + 'static,
|
||||||
|
{
|
||||||
|
type ReadFuture<'a>
|
||||||
|
where
|
||||||
|
T: 'a,
|
||||||
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
|
||||||
async move {
|
async move {
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
while pos < buf.len() {
|
while pos < buf.len() {
|
||||||
match self.wrapped.read() {
|
match self.wrapped.read() {
|
||||||
Err(nb::Error::WouldBlock) => {}
|
Err(nb::Error::WouldBlock) => {}
|
||||||
Err(_) => return Err(crate::uart::Error::Other),
|
Err(nb::Error::Other(e)) => return Err(e),
|
||||||
Ok(b) => {
|
Ok(b) => {
|
||||||
buf[pos] = b;
|
buf[pos] = b;
|
||||||
pos += 1;
|
pos += 1;
|
||||||
|
@ -149,18 +233,24 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> crate::uart::Write for BlockingAsync<T>
|
impl<T, E> embedded_hal_async::serial::Write for BlockingAsync<T>
|
||||||
where
|
where
|
||||||
T: blocking::serial::Write<u8>,
|
T: blocking::serial::Write<u8, Error = E> + serial::Read<u8, Error = E>,
|
||||||
|
E: embedded_hal_1::serial::Error + 'static,
|
||||||
{
|
{
|
||||||
#[rustfmt::skip]
|
type WriteFuture<'a>
|
||||||
type WriteFuture<'a> where T: 'a = impl Future<Output = Result<(), crate::uart::Error>> + 'a;
|
where
|
||||||
|
T: 'a,
|
||||||
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
|
||||||
async move {
|
async move { self.wrapped.bwrite_all(buf) }
|
||||||
self.wrapped
|
}
|
||||||
.bwrite_all(buf)
|
|
||||||
.map_err(|_| crate::uart::Error::Other)?;
|
type FlushFuture<'a>
|
||||||
self.wrapped.bflush().map_err(|_| crate::uart::Error::Other)
|
where
|
||||||
}
|
T: 'a,
|
||||||
|
= impl Future<Output = Result<(), Self::Error>> + 'a;
|
||||||
|
fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
|
||||||
|
async move { self.wrapped.bflush() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
use core::future::Future;
|
|
||||||
|
|
||||||
/// Wait for a pin to become high.
|
|
||||||
pub trait WaitForHigh {
|
|
||||||
type Future<'a>: Future<Output = ()> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Wait for a pin to become high.
|
|
||||||
///
|
|
||||||
/// If the pin is already high, the future completes immediately.
|
|
||||||
/// Otherwise, it completes when it becomes high.
|
|
||||||
fn wait_for_high(&mut self) -> Self::Future<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wait for a pin to become low.
|
|
||||||
pub trait WaitForLow {
|
|
||||||
type Future<'a>: Future<Output = ()> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Wait for a pin to become low.
|
|
||||||
///
|
|
||||||
/// If the pin is already low, the future completes immediately.
|
|
||||||
/// Otherwise, it completes when it becomes low.
|
|
||||||
fn wait_for_low(&mut self) -> Self::Future<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wait for a rising edge (transition from low to high)
|
|
||||||
pub trait WaitForRisingEdge {
|
|
||||||
type Future<'a>: Future<Output = ()> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Wait for a rising edge (transition from low to high)
|
|
||||||
fn wait_for_rising_edge(&mut self) -> Self::Future<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wait for a falling edge (transition from high to low)
|
|
||||||
pub trait WaitForFallingEdge {
|
|
||||||
type Future<'a>: Future<Output = ()> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Wait for a falling edge (transition from high to low)
|
|
||||||
fn wait_for_falling_edge(&'_ mut self) -> Self::Future<'_>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wait for any edge (any transition, high to low or low to high)
|
|
||||||
pub trait WaitForAnyEdge {
|
|
||||||
type Future<'a>: Future<Output = ()> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Wait for any edge (any transition, high to low or low to high)
|
|
||||||
fn wait_for_any_edge(&mut self) -> Self::Future<'_>;
|
|
||||||
}
|
|
|
@ -1,192 +0,0 @@
|
||||||
//! Async I2C API
|
|
||||||
//!
|
|
||||||
//! This API supports 7-bit and 10-bit addresses. Traits feature an `AddressMode`
|
|
||||||
//! marker type parameter. Two implementation of the `AddressMode` exist:
|
|
||||||
//! `SevenBitAddress` and `TenBitAddress`.
|
|
||||||
//!
|
|
||||||
//! Through this marker types it is possible to implement each address mode for
|
|
||||||
//! the traits independently in `embedded-hal` implementations and device drivers
|
|
||||||
//! can depend only on the mode that they support.
|
|
||||||
//!
|
|
||||||
//! Additionally, the I2C 10-bit address mode has been developed to be fully
|
|
||||||
//! backwards compatible with the 7-bit address mode. This allows for a
|
|
||||||
//! software-emulated 10-bit addressing implementation if the address mode
|
|
||||||
//! is not supported by the hardware.
|
|
||||||
//!
|
|
||||||
//! Since 7-bit addressing is the mode of the majority of I2C devices,
|
|
||||||
//! `SevenBitAddress` has been set as default mode and thus can be omitted if desired.
|
|
||||||
//!
|
|
||||||
//! ### Device driver compatible only with 7-bit addresses
|
|
||||||
//!
|
|
||||||
//! For demonstration purposes the address mode parameter has been omitted in this example.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # use embassy_traits::i2c::I2c;
|
|
||||||
//! const ADDR: u8 = 0x15;
|
|
||||||
//! # const TEMP_REGISTER: u8 = 0x1;
|
|
||||||
//! pub struct TemperatureSensorDriver<I2C> {
|
|
||||||
//! i2c: I2C,
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl<I2C, E> TemperatureSensorDriver<I2C>
|
|
||||||
//! where
|
|
||||||
//! I2C: I2c<Error = E>,
|
|
||||||
//! {
|
|
||||||
//! pub fn read_temperature(&mut self) -> Result<u8, E> {
|
|
||||||
//! let mut temp = [0];
|
|
||||||
//! self.i2c
|
|
||||||
//! .write_read(ADDR, &[TEMP_REGISTER], &mut temp)
|
|
||||||
//! .await
|
|
||||||
//! .and(Ok(temp[0]))
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! ### Device driver compatible only with 10-bit addresses
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # use embassy_traits::i2c::{TenBitAddress, I2c};
|
|
||||||
//! const ADDR: u16 = 0x158;
|
|
||||||
//! # const TEMP_REGISTER: u8 = 0x1;
|
|
||||||
//! pub struct TemperatureSensorDriver<I2C> {
|
|
||||||
//! i2c: I2C,
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl<I2C, E> TemperatureSensorDriver<I2C>
|
|
||||||
//! where
|
|
||||||
//! I2C: I2c<TenBitAddress, Error = E>,
|
|
||||||
//! {
|
|
||||||
//! pub fn read_temperature(&mut self) -> Result<u8, E> {
|
|
||||||
//! let mut temp = [0];
|
|
||||||
//! self.i2c
|
|
||||||
//! .write_read(ADDR, &[TEMP_REGISTER], &mut temp)
|
|
||||||
//! .await
|
|
||||||
//! .and(Ok(temp[0]))
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
use core::future::Future;
|
|
||||||
|
|
||||||
mod private {
|
|
||||||
pub trait Sealed {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Address mode (7-bit / 10-bit)
|
|
||||||
///
|
|
||||||
/// Note: This trait is sealed and should not be implemented outside of this crate.
|
|
||||||
pub trait AddressMode: private::Sealed {}
|
|
||||||
|
|
||||||
/// 7-bit address mode type
|
|
||||||
pub type SevenBitAddress = u8;
|
|
||||||
|
|
||||||
/// 10-bit address mode type
|
|
||||||
pub type TenBitAddress = u16;
|
|
||||||
|
|
||||||
impl private::Sealed for SevenBitAddress {}
|
|
||||||
impl private::Sealed for TenBitAddress {}
|
|
||||||
|
|
||||||
impl AddressMode for SevenBitAddress {}
|
|
||||||
|
|
||||||
impl AddressMode for TenBitAddress {}
|
|
||||||
|
|
||||||
pub trait I2c<A: AddressMode = SevenBitAddress> {
|
|
||||||
/// Error type
|
|
||||||
type Error;
|
|
||||||
|
|
||||||
type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Reads enough bytes from slave with `address` to fill `buffer`
|
|
||||||
///
|
|
||||||
/// # I2C Events (contract)
|
|
||||||
///
|
|
||||||
/// ``` text
|
|
||||||
/// Master: ST SAD+R MAK MAK ... NMAK SP
|
|
||||||
/// Slave: SAK B0 B1 ... BN
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Where
|
|
||||||
///
|
|
||||||
/// - `ST` = start condition
|
|
||||||
/// - `SAD+R` = slave address followed by bit 1 to indicate reading
|
|
||||||
/// - `SAK` = slave acknowledge
|
|
||||||
/// - `Bi` = ith byte of data
|
|
||||||
/// - `MAK` = master acknowledge
|
|
||||||
/// - `NMAK` = master no acknowledge
|
|
||||||
/// - `SP` = stop condition
|
|
||||||
fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Self::ReadFuture<'a>;
|
|
||||||
|
|
||||||
/// Sends bytes to slave with address `address`
|
|
||||||
///
|
|
||||||
/// # I2C Events (contract)
|
|
||||||
///
|
|
||||||
/// ``` text
|
|
||||||
/// Master: ST SAD+W B0 B1 ... BN SP
|
|
||||||
/// Slave: SAK SAK SAK ... SAK
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Where
|
|
||||||
///
|
|
||||||
/// - `ST` = start condition
|
|
||||||
/// - `SAD+W` = slave address followed by bit 0 to indicate writing
|
|
||||||
/// - `SAK` = slave acknowledge
|
|
||||||
/// - `Bi` = ith byte of data
|
|
||||||
/// - `SP` = stop condition
|
|
||||||
fn write<'a>(&'a mut self, address: A, bytes: &'a [u8]) -> Self::WriteFuture<'a>;
|
|
||||||
|
|
||||||
/// Sends bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
|
|
||||||
/// single transaction*
|
|
||||||
///
|
|
||||||
/// # I2C Events (contract)
|
|
||||||
///
|
|
||||||
/// ``` text
|
|
||||||
/// Master: ST SAD+W O0 O1 ... OM SR SAD+R MAK MAK ... NMAK SP
|
|
||||||
/// Slave: SAK SAK SAK ... SAK SAK I0 I1 ... IN
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Where
|
|
||||||
///
|
|
||||||
/// - `ST` = start condition
|
|
||||||
/// - `SAD+W` = slave address followed by bit 0 to indicate writing
|
|
||||||
/// - `SAK` = slave acknowledge
|
|
||||||
/// - `Oi` = ith outgoing byte of data
|
|
||||||
/// - `SR` = repeated start condition
|
|
||||||
/// - `SAD+R` = slave address followed by bit 1 to indicate reading
|
|
||||||
/// - `Ii` = ith incoming byte of data
|
|
||||||
/// - `MAK` = master acknowledge
|
|
||||||
/// - `NMAK` = master no acknowledge
|
|
||||||
/// - `SP` = stop condition
|
|
||||||
fn write_read<'a>(
|
|
||||||
&'a mut self,
|
|
||||||
address: A,
|
|
||||||
bytes: &'a [u8],
|
|
||||||
buffer: &'a mut [u8],
|
|
||||||
) -> Self::WriteReadFuture<'a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait WriteIter<A: AddressMode = SevenBitAddress> {
|
|
||||||
/// Error type
|
|
||||||
type Error;
|
|
||||||
|
|
||||||
type WriteIterFuture<'a, V>: Future<Output = Result<(), Self::Error>> + 'a
|
|
||||||
where
|
|
||||||
V: 'a + IntoIterator<Item = u8>,
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Sends bytes to slave with address `address`
|
|
||||||
///
|
|
||||||
/// # I2C Events (contract)
|
|
||||||
///
|
|
||||||
/// Same as `I2c::write`
|
|
||||||
fn write_iter<'a, U>(&'a mut self, address: A, bytes: U) -> Self::WriteIterFuture<'a, U>
|
|
||||||
where
|
|
||||||
U: IntoIterator<Item = u8> + 'a;
|
|
||||||
}
|
|
|
@ -5,8 +5,4 @@
|
||||||
pub mod adapter;
|
pub mod adapter;
|
||||||
pub mod delay;
|
pub mod delay;
|
||||||
pub mod flash;
|
pub mod flash;
|
||||||
pub mod gpio;
|
|
||||||
pub mod i2c;
|
|
||||||
pub mod rng;
|
pub mod rng;
|
||||||
pub mod spi;
|
|
||||||
pub mod uart;
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
//! Async SPI API
|
|
||||||
|
|
||||||
use core::future::Future;
|
|
||||||
|
|
||||||
/// Full duplex (master mode)
|
|
||||||
///
|
|
||||||
/// # Notes
|
|
||||||
///
|
|
||||||
/// - It's the task of the user of this interface to manage the slave select lines
|
|
||||||
///
|
|
||||||
/// - Due to how full duplex SPI works each `read` call must be preceded by a `write` call.
|
|
||||||
///
|
|
||||||
/// - `read` calls only return the data received with the last `write` call.
|
|
||||||
/// Previously received data is discarded
|
|
||||||
///
|
|
||||||
/// - Data is only guaranteed to be clocked out when the `read` call succeeds.
|
|
||||||
/// The slave select line shouldn't be released before that.
|
|
||||||
///
|
|
||||||
/// - Some SPIs can work with 8-bit *and* 16-bit words. You can overload this trait with different
|
|
||||||
/// `Word` types to allow operation in both modes.
|
|
||||||
|
|
||||||
pub trait Spi<Word> {
|
|
||||||
/// An enumeration of SPI errors
|
|
||||||
type Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FullDuplex<Word>: Spi<Word> + Write<Word> + Read<Word> {
|
|
||||||
type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
Word: 'a;
|
|
||||||
|
|
||||||
/// The `read` array must be at least as long as the `write` array,
|
|
||||||
/// but is guaranteed to only be filled with bytes equal to the
|
|
||||||
/// length of the `write` array.
|
|
||||||
fn read_write<'a>(
|
|
||||||
&'a mut self,
|
|
||||||
read: &'a mut [Word],
|
|
||||||
write: &'a [Word],
|
|
||||||
) -> Self::WriteReadFuture<'a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Write<Word>: Spi<Word> {
|
|
||||||
type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
Word: 'a;
|
|
||||||
|
|
||||||
/// Writes `data` to the peripheral, ignoring all the incoming words.
|
|
||||||
fn write<'a>(&'a mut self, data: &'a [Word]) -> Self::WriteFuture<'a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Read<Word>: Write<Word> {
|
|
||||||
type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
Word: 'a;
|
|
||||||
|
|
||||||
/// Reads words into `data` from the peripheral.
|
|
||||||
fn read<'a>(&'a mut self, data: &'a mut [Word]) -> Self::ReadFuture<'a>;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
use core::future::Future;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
|
||||||
#[non_exhaustive]
|
|
||||||
pub enum Error {
|
|
||||||
Other,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Read {
|
|
||||||
type ReadFuture<'a>: Future<Output = Result<(), Error>>
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Receive into the buffer until the buffer is full.
|
|
||||||
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ReadUntilIdle {
|
|
||||||
type ReadUntilIdleFuture<'a>: Future<Output = Result<usize, Error>>
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Receive into the buffer until the buffer is full or the line is idle after some bytes are received
|
|
||||||
/// Return the number of bytes received
|
|
||||||
fn read_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Write {
|
|
||||||
type WriteFuture<'a>: Future<Output = Result<(), Error>>
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
|
|
||||||
/// Write all bytes in `buf`.
|
|
||||||
fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a>;
|
|
||||||
}
|
|
|
@ -10,7 +10,6 @@ use embassy::executor::Spawner;
|
||||||
use embassy_stm32::spi::{Config, Spi};
|
use embassy_stm32::spi::{Config, Spi};
|
||||||
use embassy_stm32::time::Hertz;
|
use embassy_stm32::time::Hertz;
|
||||||
use embassy_stm32::Peripherals;
|
use embassy_stm32::Peripherals;
|
||||||
use embassy_traits::spi::FullDuplex;
|
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
use heapless::String;
|
use heapless::String;
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
||||||
let mut write: String<128> = String::new();
|
let mut write: String<128> = String::new();
|
||||||
let mut read = [0; 128];
|
let mut read = [0; 128];
|
||||||
core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
|
core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
|
||||||
spi.read_write(&mut read[0..write.len()], write.as_bytes())
|
spi.transfer(&mut read[0..write.len()], write.as_bytes())
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
info!("read via spi+dma: {}", from_utf8(&read).unwrap());
|
info!("read via spi+dma: {}", from_utf8(&read).unwrap());
|
||||||
|
|
|
@ -10,7 +10,7 @@ resolver = "2"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
|
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
|
||||||
embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
|
embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
|
||||||
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac"] }
|
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
|
||||||
embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] }
|
embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] }
|
||||||
embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] }
|
embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] }
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ defmt-rtt = "0.3"
|
||||||
cortex-m = "0.7.3"
|
cortex-m = "0.7.3"
|
||||||
cortex-m-rt = "0.7.0"
|
cortex-m-rt = "0.7.0"
|
||||||
embedded-hal = "0.2.6"
|
embedded-hal = "0.2.6"
|
||||||
|
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
|
||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
|
|
|
@ -128,7 +128,7 @@ mod ov7725 {
|
||||||
use defmt::Format;
|
use defmt::Format;
|
||||||
use embassy::time::{Duration, Timer};
|
use embassy::time::{Duration, Timer};
|
||||||
use embassy_stm32::rcc::{Mco, McoInstance};
|
use embassy_stm32::rcc::{Mco, McoInstance};
|
||||||
use embassy_traits::i2c::I2c;
|
use embedded_hal_async::i2c::I2c;
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum RgbFormat {
|
pub enum RgbFormat {
|
||||||
|
|
|
@ -9,7 +9,6 @@ use core::fmt::Write;
|
||||||
use embassy::executor::Executor;
|
use embassy::executor::Executor;
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_stm32::time::U32Ext;
|
use embassy_stm32::time::U32Ext;
|
||||||
use embassy_traits::spi::FullDuplex;
|
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
use core::str::from_utf8;
|
use core::str::from_utf8;
|
||||||
|
@ -24,8 +23,8 @@ async fn main_task(mut spi: spi::Spi<'static, SPI3, DMA1_CH3, DMA1_CH4>) {
|
||||||
let mut write: String<128> = String::new();
|
let mut write: String<128> = String::new();
|
||||||
let mut read = [0; 128];
|
let mut read = [0; 128];
|
||||||
core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
|
core::write!(&mut write, "Hello DMA World {}!\r\n", n).unwrap();
|
||||||
// read_write will slice the &mut read down to &write's actual length.
|
// transfer will slice the &mut read down to &write's actual length.
|
||||||
spi.read_write(&mut read, write.as_bytes()).await.ok();
|
spi.transfer(&mut read, write.as_bytes()).await.ok();
|
||||||
info!("read via spi+dma: {}", from_utf8(&read).unwrap());
|
info!("read via spi+dma: {}", from_utf8(&read).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ resolver = "2"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
|
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
|
||||||
embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
|
embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
|
||||||
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "memory-x"] }
|
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"] }
|
embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"] }
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ resolver = "2"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt" ] }
|
embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt" ] }
|
||||||
embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
|
embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
|
||||||
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti"] }
|
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits"] }
|
||||||
|
|
||||||
defmt = "0.3"
|
defmt = "0.3"
|
||||||
defmt-rtt = "0.3"
|
defmt-rtt = "0.3"
|
||||||
|
@ -18,6 +18,7 @@ defmt-rtt = "0.3"
|
||||||
cortex-m = "0.7.3"
|
cortex-m = "0.7.3"
|
||||||
cortex-m-rt = "0.7.0"
|
cortex-m-rt = "0.7.0"
|
||||||
embedded-hal = "0.2.6"
|
embedded-hal = "0.2.6"
|
||||||
|
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
|
||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
|
|
|
@ -11,7 +11,8 @@ use embassy_stm32::i2c::I2c;
|
||||||
use embassy_stm32::interrupt;
|
use embassy_stm32::interrupt;
|
||||||
use embassy_stm32::time::Hertz;
|
use embassy_stm32::time::Hertz;
|
||||||
use embassy_stm32::Peripherals;
|
use embassy_stm32::Peripherals;
|
||||||
use embassy_traits::{adapter::BlockingAsync, i2c::I2c as _};
|
use embassy_traits::adapter::BlockingAsync;
|
||||||
|
use embedded_hal_async::i2c::I2c as I2cTrait;
|
||||||
use example_common::{info, unwrap};
|
use example_common::{info, unwrap};
|
||||||
|
|
||||||
const ADDRESS: u8 = 0x5F;
|
const ADDRESS: u8 = 0x5F;
|
||||||
|
|
|
@ -11,7 +11,8 @@ use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
|
||||||
use embassy_stm32::spi::{Config, Spi};
|
use embassy_stm32::spi::{Config, Spi};
|
||||||
use embassy_stm32::time::Hertz;
|
use embassy_stm32::time::Hertz;
|
||||||
use embassy_stm32::Peripherals;
|
use embassy_stm32::Peripherals;
|
||||||
use embassy_traits::{adapter::BlockingAsync, spi::FullDuplex};
|
use embassy_traits::adapter::BlockingAsync;
|
||||||
|
use embedded_hal_async::spi::ReadWrite;
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
#[embassy::main]
|
#[embassy::main]
|
||||||
|
@ -47,10 +48,10 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
||||||
info!("waiting for ready");
|
info!("waiting for ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
let write = [0x0A; 10];
|
let write: [u8; 10] = [0x0A; 10];
|
||||||
let mut read = [0; 10];
|
let mut read: [u8; 10] = [0; 10];
|
||||||
cs.set_low();
|
cs.set_low();
|
||||||
spi.read_write(&mut read, &write).await.ok();
|
spi.transfer(&mut read, &write).await.ok();
|
||||||
cs.set_high();
|
cs.set_high();
|
||||||
info!("xfer {=[u8]:x}", read);
|
info!("xfer {=[u8]:x}", read);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ use embassy_stm32::gpio::{Input, Level, Output, Pull, Speed};
|
||||||
use embassy_stm32::spi::{Config, Spi};
|
use embassy_stm32::spi::{Config, Spi};
|
||||||
use embassy_stm32::time::Hertz;
|
use embassy_stm32::time::Hertz;
|
||||||
use embassy_stm32::Peripherals;
|
use embassy_stm32::Peripherals;
|
||||||
use embassy_traits::spi::FullDuplex;
|
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
#[embassy::main]
|
#[embassy::main]
|
||||||
|
@ -47,7 +46,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
||||||
let write = [0x0A; 10];
|
let write = [0x0A; 10];
|
||||||
let mut read = [0; 10];
|
let mut read = [0; 10];
|
||||||
cs.set_low();
|
cs.set_low();
|
||||||
spi.read_write(&mut read, &write).await.ok();
|
spi.transfer(&mut read, &write).await.ok();
|
||||||
cs.set_high();
|
cs.set_high();
|
||||||
info!("xfer {=[u8]:x}", read);
|
info!("xfer {=[u8]:x}", read);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,11 @@
|
||||||
mod example_common;
|
mod example_common;
|
||||||
|
|
||||||
use embassy::executor::Spawner;
|
use embassy::executor::Spawner;
|
||||||
use embassy::traits::{
|
use embassy::traits::adapter::BlockingAsync;
|
||||||
adapter::BlockingAsync,
|
|
||||||
uart::{Read, Write},
|
|
||||||
};
|
|
||||||
use embassy_stm32::dma::NoDma;
|
use embassy_stm32::dma::NoDma;
|
||||||
use embassy_stm32::usart::{Config, Uart};
|
use embassy_stm32::usart::{Config, Uart};
|
||||||
use embassy_stm32::Peripherals;
|
use embassy_stm32::Peripherals;
|
||||||
|
use embedded_hal_async::serial::{Read, Write};
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
#[embassy::main]
|
#[embassy::main]
|
||||||
|
|
|
@ -23,6 +23,7 @@ defmt-rtt = "0.3.0"
|
||||||
cortex-m = "0.7.3"
|
cortex-m = "0.7.3"
|
||||||
cortex-m-rt = "0.7.0"
|
cortex-m-rt = "0.7.0"
|
||||||
embedded-hal = "0.2.6"
|
embedded-hal = "0.2.6"
|
||||||
|
embedded-hal-async = { version = "0.0.1", git = "https://github.com/embassy-rs/embedded-hal", branch = "embassy"}
|
||||||
panic-probe = { version = "0.3.0", features = ["print-defmt"] }
|
panic-probe = { version = "0.3.0", features = ["print-defmt"] }
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
|
|
@ -9,7 +9,6 @@ use embassy::executor::Spawner;
|
||||||
use embassy_stm32::spi::{self, Spi};
|
use embassy_stm32::spi::{self, Spi};
|
||||||
use embassy_stm32::time::Hertz;
|
use embassy_stm32::time::Hertz;
|
||||||
use embassy_stm32::Peripherals;
|
use embassy_stm32::Peripherals;
|
||||||
use embassy_traits::spi::FullDuplex;
|
|
||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
#[embassy::main(config = "config()")]
|
#[embassy::main(config = "config()")]
|
||||||
|
@ -43,7 +42,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
||||||
// Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor.
|
// Arduino pins D11 and D12 (MOSI-MISO) are connected together with a 1K resistor.
|
||||||
// so we should get the data we sent back.
|
// so we should get the data we sent back.
|
||||||
let mut buf = [0; 9];
|
let mut buf = [0; 9];
|
||||||
spi.read_write(&mut buf, &data).await.unwrap();
|
spi.transfer(&mut buf, &data).await.unwrap();
|
||||||
assert_eq!(buf, data);
|
assert_eq!(buf, data);
|
||||||
|
|
||||||
info!("Test OK");
|
info!("Test OK");
|
||||||
|
|
Loading…
Reference in a new issue