mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 16:23:10 +00:00
Merge pull request #6 from xoviat/stm32f4
Add stm32f4xx series serial driver
This commit is contained in:
commit
61a7cf5c3d
@ -3,7 +3,9 @@
|
||||
members = [
|
||||
"embassy",
|
||||
"embassy-nrf",
|
||||
"embassy-stm32f4",
|
||||
"embassy-nrf-examples",
|
||||
"embassy-stm32f4-examples",
|
||||
"embassy-macros",
|
||||
]
|
||||
|
||||
|
39
embassy-stm32f4-examples/Cargo.toml
Normal file
39
embassy-stm32f4-examples/Cargo.toml
Normal file
@ -0,0 +1,39 @@
|
||||
[package]
|
||||
authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"]
|
||||
edition = "2018"
|
||||
name = "embassy-stm32f4-examples"
|
||||
version = "0.1.0"
|
||||
|
||||
[features]
|
||||
default = [
|
||||
"defmt-default",
|
||||
]
|
||||
defmt-default = []
|
||||
defmt-trace = []
|
||||
defmt-debug = []
|
||||
defmt-info = []
|
||||
defmt-warn = []
|
||||
defmt-error = []
|
||||
|
||||
|
||||
[dependencies]
|
||||
embassy = { version = "0.1.0", path = "../embassy", features = ["defmt", "defmt-trace"] }
|
||||
embassy-stm32f4 = { version = "*", path = "../embassy-stm32f4", features = ["stm32f405"] }
|
||||
|
||||
defmt = "0.1.3"
|
||||
defmt-rtt = "0.1.0"
|
||||
|
||||
cortex-m = { version = "0.6.3" }
|
||||
cortex-m-rt = "0.6.13"
|
||||
embedded-hal = { version = "0.2.4" }
|
||||
panic-probe = "0.1.0"
|
||||
stm32f4xx-hal = { version = "0.8.3", features = ["rt", "stm32f405"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"}
|
||||
futures = { version = "0.3.8", default-features = false, features = ["async-await"] }
|
||||
cortex-m-rtic = "0.5"
|
||||
rtt-target = { version = "0.3", features = ["cortex-m"] }
|
||||
|
||||
|
||||
|
||||
[[bin]]
|
||||
name = "serial"
|
||||
path = "src/serial.rs"
|
64
embassy-stm32f4-examples/src/serial.rs
Normal file
64
embassy-stm32f4-examples/src/serial.rs
Normal file
@ -0,0 +1,64 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(trait_alias)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
// extern crate panic_halt;
|
||||
|
||||
use cortex_m::singleton;
|
||||
use cortex_m_rt::entry;
|
||||
use embassy::executor::{task, Executor};
|
||||
use embassy::util::Forever;
|
||||
use embassy_stm32f4::interrupt;
|
||||
use embassy_stm32f4::serial;
|
||||
use stm32f4xx_hal::stm32;
|
||||
use stm32f4xx_hal::{prelude::*, serial::config};
|
||||
|
||||
#[task]
|
||||
async fn run(dp: stm32::Peripherals, cp: cortex_m::Peripherals) {
|
||||
// https://gist.github.com/thalesfragoso/a07340c5df6eee3b04c42fdc69ecdcb1
|
||||
let gpioa = dp.GPIOA.split();
|
||||
let rcc = dp.RCC.constrain();
|
||||
|
||||
let clocks = rcc
|
||||
.cfgr
|
||||
.use_hse(16.mhz())
|
||||
.sysclk(48.mhz())
|
||||
.pclk1(24.mhz())
|
||||
.freeze();
|
||||
|
||||
let mut serial = serial::Serial::new(
|
||||
gpioa.pa9.into_alternate_af7(),
|
||||
gpioa.pa10.into_alternate_af7(),
|
||||
interrupt::take!(DMA2_STREAM7),
|
||||
interrupt::take!(DMA2_STREAM2),
|
||||
interrupt::take!(USART1),
|
||||
dp.DMA2,
|
||||
dp.USART1,
|
||||
config::Parity::ParityNone,
|
||||
9600.bps(),
|
||||
clocks,
|
||||
);
|
||||
|
||||
let buf = singleton!(: [u8; 30] = [0; 30]).unwrap();
|
||||
|
||||
buf[5] = 0x01;
|
||||
|
||||
serial.send(buf).await;
|
||||
}
|
||||
|
||||
static EXECUTOR: Forever<Executor> = Forever::new();
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let dp = stm32::Peripherals::take().unwrap();
|
||||
let cp = cortex_m::peripheral::Peripherals::take().unwrap();
|
||||
|
||||
let executor = EXECUTOR.put(Executor::new(cortex_m::asm::sev));
|
||||
executor.spawn(run(dp, cp));
|
||||
|
||||
loop {
|
||||
executor.run();
|
||||
cortex_m::asm::wfe();
|
||||
}
|
||||
}
|
43
embassy-stm32f4/Cargo.toml
Normal file
43
embassy-stm32f4/Cargo.toml
Normal file
@ -0,0 +1,43 @@
|
||||
[package]
|
||||
name = "embassy-stm32f4"
|
||||
version = "0.1.0"
|
||||
authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"]
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
defmt-trace = [ ]
|
||||
defmt-debug = [ ]
|
||||
defmt-info = [ ]
|
||||
defmt-warn = [ ]
|
||||
defmt-error = [ ]
|
||||
|
||||
stm32f401 = ["stm32f4xx-hal/stm32f401"]
|
||||
stm32f405 = ["stm32f4xx-hal/stm32f405"]
|
||||
stm32f407 = ["stm32f4xx-hal/stm32f407"]
|
||||
stm32f410 = ["stm32f4xx-hal/stm32f410"]
|
||||
stm32f411 = ["stm32f4xx-hal/stm32f411"]
|
||||
stm32f412 = ["stm32f4xx-hal/stm32f412"]
|
||||
stm32f413 = ["stm32f4xx-hal/stm32f413"]
|
||||
stm32f415 = ["stm32f4xx-hal/stm32f405"]
|
||||
stm32f417 = ["stm32f4xx-hal/stm32f407"]
|
||||
stm32f423 = ["stm32f4xx-hal/stm32f413"]
|
||||
stm32f427 = ["stm32f4xx-hal/stm32f427"]
|
||||
stm32f429 = ["stm32f4xx-hal/stm32f429"]
|
||||
stm32f437 = ["stm32f4xx-hal/stm32f427"]
|
||||
stm32f439 = ["stm32f4xx-hal/stm32f429"]
|
||||
stm32f446 = ["stm32f4xx-hal/stm32f446"]
|
||||
stm32f469 = ["stm32f4xx-hal/stm32f469"]
|
||||
stm32f479 = ["stm32f4xx-hal/stm32f469"]
|
||||
|
||||
default = ["stm32f405"]
|
||||
|
||||
[dependencies]
|
||||
embassy = { version = "0.1.0", path = "../embassy" }
|
||||
|
||||
defmt = { version = "0.1.3", optional = true }
|
||||
log = { version = "0.4.11", optional = true }
|
||||
cortex-m-rt = "0.6.13"
|
||||
cortex-m = { version = "0.6.4" }
|
||||
embedded-hal = { version = "0.2.4" }
|
||||
embedded-dma = { version = "0.1.2" }
|
||||
stm32f4xx-hal = { version = "0.8.3", features = ["rt"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"}
|
118
embassy-stm32f4/src/fmt.rs
Normal file
118
embassy-stm32f4/src/fmt.rs
Normal file
@ -0,0 +1,118 @@
|
||||
#![macro_use]
|
||||
|
||||
#[cfg(all(feature = "defmt", feature = "log"))]
|
||||
compile_error!("You may not enable both `defmt` and `log` features.");
|
||||
|
||||
pub use fmt::*;
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
mod fmt {
|
||||
pub use defmt::{
|
||||
assert, assert_eq, assert_ne, debug, debug_assert, debug_assert_eq, debug_assert_ne, error,
|
||||
info, panic, todo, trace, unreachable, unwrap, warn,
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "log")]
|
||||
mod fmt {
|
||||
pub use core::{
|
||||
assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo,
|
||||
unreachable,
|
||||
};
|
||||
pub use log::{debug, error, info, trace, warn};
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "defmt", feature = "log")))]
|
||||
mod fmt {
|
||||
#![macro_use]
|
||||
|
||||
pub use core::{
|
||||
assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo,
|
||||
unreachable,
|
||||
};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! trace {
|
||||
($($msg:expr),+ $(,)?) => {
|
||||
()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! debug {
|
||||
($($msg:expr),+ $(,)?) => {
|
||||
()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! info {
|
||||
($($msg:expr),+ $(,)?) => {
|
||||
()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! warn {
|
||||
($($msg:expr),+ $(,)?) => {
|
||||
()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error {
|
||||
($($msg:expr),+ $(,)?) => {
|
||||
()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
#[macro_export]
|
||||
macro_rules! unwrap {
|
||||
($arg:expr) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
($arg:expr, $($msg:expr),+ $(,)? ) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct NoneError;
|
||||
|
||||
pub trait Try {
|
||||
type Ok;
|
||||
type Error;
|
||||
fn into_result(self) -> Result<Self::Ok, Self::Error>;
|
||||
}
|
||||
|
||||
impl<T> Try for Option<T> {
|
||||
type Ok = T;
|
||||
type Error = NoneError;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Result<T, NoneError> {
|
||||
self.ok_or(NoneError)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Try for Result<T, E> {
|
||||
type Ok = T;
|
||||
type Error = E;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
193
embassy-stm32f4/src/interrupt.rs
Normal file
193
embassy-stm32f4/src/interrupt.rs
Normal file
@ -0,0 +1,193 @@
|
||||
//! Interrupt management
|
||||
//!
|
||||
//! This module implements an API for managing interrupts compatible with
|
||||
//! nrf_softdevice::interrupt. Intended for switching between the two at compile-time.
|
||||
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
|
||||
use crate::pac::NVIC_PRIO_BITS;
|
||||
|
||||
// Re-exports
|
||||
pub use crate::pac::Interrupt;
|
||||
pub use crate::pac::Interrupt::*; // needed for cortex-m-rt #[interrupt]
|
||||
pub use cortex_m::interrupt::{CriticalSection, Mutex};
|
||||
pub use embassy::interrupt::{declare, take, OwnedInterrupt};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[repr(u8)]
|
||||
pub enum Priority {
|
||||
Level0 = 0,
|
||||
Level1 = 1,
|
||||
Level2 = 2,
|
||||
Level3 = 3,
|
||||
Level4 = 4,
|
||||
Level5 = 5,
|
||||
Level6 = 6,
|
||||
Level7 = 7,
|
||||
Level8 = 8,
|
||||
Level9 = 9,
|
||||
Level10 = 10,
|
||||
Level11 = 11,
|
||||
Level12 = 12,
|
||||
Level13 = 13,
|
||||
Level14 = 14,
|
||||
Level15 = 15,
|
||||
}
|
||||
|
||||
impl From<u8> for Priority {
|
||||
fn from(priority: u8) -> Self {
|
||||
match priority >> (8 - NVIC_PRIO_BITS) {
|
||||
0 => Self::Level0,
|
||||
1 => Self::Level1,
|
||||
2 => Self::Level2,
|
||||
3 => Self::Level3,
|
||||
4 => Self::Level4,
|
||||
5 => Self::Level5,
|
||||
6 => Self::Level6,
|
||||
7 => Self::Level7,
|
||||
8 => Self::Level8,
|
||||
9 => Self::Level9,
|
||||
10 => Self::Level10,
|
||||
11 => Self::Level11,
|
||||
12 => Self::Level12,
|
||||
13 => Self::Level13,
|
||||
14 => Self::Level14,
|
||||
15 => Self::Level15,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Priority> for u8 {
|
||||
fn from(p: Priority) -> Self {
|
||||
(p as u8) << (8 - NVIC_PRIO_BITS)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn free<F, R>(f: F) -> R
|
||||
where
|
||||
F: FnOnce(&CriticalSection) -> R,
|
||||
{
|
||||
unsafe {
|
||||
// TODO: assert that we're in privileged level
|
||||
// Needed because disabling irqs in non-privileged level is a noop, which would break safety.
|
||||
|
||||
let primask: u32;
|
||||
asm!("mrs {}, PRIMASK", out(reg) primask);
|
||||
|
||||
asm!("cpsid i");
|
||||
|
||||
// Prevent compiler from reordering operations inside/outside the critical section.
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
let r = f(&CriticalSection::new());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
if primask & 1 == 0 {
|
||||
asm!("cpsie i");
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "stm32f405")]
|
||||
mod irqs {
|
||||
use super::*;
|
||||
declare!(WWDG);
|
||||
declare!(PVD);
|
||||
declare!(TAMP_STAMP);
|
||||
declare!(RTC_WKUP);
|
||||
// declare!(FLASH);
|
||||
declare!(RCC);
|
||||
declare!(EXTI0);
|
||||
declare!(EXTI1);
|
||||
declare!(EXTI2);
|
||||
declare!(EXTI3);
|
||||
declare!(EXTI4);
|
||||
declare!(DMA1_STREAM0);
|
||||
declare!(DMA1_STREAM1);
|
||||
declare!(DMA1_STREAM2);
|
||||
declare!(DMA1_STREAM3);
|
||||
declare!(DMA1_STREAM4);
|
||||
declare!(DMA1_STREAM5);
|
||||
declare!(DMA1_STREAM6);
|
||||
declare!(ADC);
|
||||
declare!(CAN1_TX);
|
||||
declare!(CAN1_RX0);
|
||||
declare!(CAN1_RX1);
|
||||
declare!(CAN1_SCE);
|
||||
declare!(EXTI9_5);
|
||||
declare!(TIM1_BRK_TIM9);
|
||||
declare!(TIM1_UP_TIM10);
|
||||
declare!(TIM1_TRG_COM_TIM11);
|
||||
declare!(TIM1_CC);
|
||||
declare!(TIM2);
|
||||
declare!(TIM3);
|
||||
declare!(TIM4);
|
||||
declare!(I2C1_EV);
|
||||
declare!(I2C1_ER);
|
||||
declare!(I2C2_EV);
|
||||
declare!(I2C2_ER);
|
||||
declare!(SPI1);
|
||||
declare!(SPI2);
|
||||
declare!(USART1);
|
||||
declare!(USART2);
|
||||
declare!(USART3);
|
||||
declare!(EXTI15_10);
|
||||
declare!(RTC_ALARM);
|
||||
declare!(OTG_FS_WKUP);
|
||||
declare!(TIM8_BRK_TIM12);
|
||||
declare!(TIM8_UP_TIM13);
|
||||
declare!(TIM8_TRG_COM_TIM14);
|
||||
declare!(TIM8_CC);
|
||||
declare!(DMA1_STREAM7);
|
||||
// declare!(FMC);
|
||||
declare!(SDIO);
|
||||
declare!(TIM5);
|
||||
declare!(SPI3);
|
||||
declare!(UART4);
|
||||
declare!(UART5);
|
||||
declare!(TIM6_DAC);
|
||||
declare!(TIM7);
|
||||
declare!(DMA2_STREAM0);
|
||||
declare!(DMA2_STREAM1);
|
||||
declare!(DMA2_STREAM2);
|
||||
declare!(DMA2_STREAM3);
|
||||
declare!(DMA2_STREAM4);
|
||||
declare!(ETH);
|
||||
declare!(ETH_WKUP);
|
||||
declare!(CAN2_TX);
|
||||
declare!(CAN2_RX0);
|
||||
declare!(CAN2_RX1);
|
||||
declare!(CAN2_SCE);
|
||||
declare!(OTG_FS);
|
||||
declare!(DMA2_STREAM5);
|
||||
declare!(DMA2_STREAM6);
|
||||
declare!(DMA2_STREAM7);
|
||||
declare!(USART6);
|
||||
declare!(I2C3_EV);
|
||||
declare!(I2C3_ER);
|
||||
declare!(OTG_HS_EP1_OUT);
|
||||
declare!(OTG_HS_EP1_IN);
|
||||
declare!(OTG_HS_WKUP);
|
||||
declare!(OTG_HS);
|
||||
declare!(DCMI);
|
||||
declare!(CRYP);
|
||||
declare!(HASH_RNG);
|
||||
declare!(FPU);
|
||||
// declare!(UART7);
|
||||
// declare!(UART8);
|
||||
// declare!(SPI4);
|
||||
// declare!(SPI5);
|
||||
// declare!(SPI6);
|
||||
// declare!(SAI1);
|
||||
declare!(LCD_TFT);
|
||||
declare!(LCD_TFT_1);
|
||||
// declare!(DMA2D);
|
||||
}
|
||||
|
||||
pub use irqs::*;
|
317
embassy-stm32f4/src/lib.rs
Normal file
317
embassy-stm32f4/src/lib.rs
Normal file
@ -0,0 +1,317 @@
|
||||
#![no_std]
|
||||
#![feature(generic_associated_types)]
|
||||
#![feature(asm)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(let_chains)]
|
||||
|
||||
#[cfg(not(any(
|
||||
feature = "stm32f401",
|
||||
feature = "stm32f405",
|
||||
feature = "stm32f407",
|
||||
feature = "stm32f410",
|
||||
feature = "stm32f411",
|
||||
feature = "stm32f412",
|
||||
feature = "stm32f413",
|
||||
feature = "stm32f415",
|
||||
feature = "stm32f417",
|
||||
feature = "stm32f423",
|
||||
feature = "stm32f427",
|
||||
feature = "stm32f429",
|
||||
feature = "stm32f437",
|
||||
feature = "stm32f439",
|
||||
feature = "stm32f446",
|
||||
feature = "stm32f469",
|
||||
feature = "stm32f479",
|
||||
)))]
|
||||
compile_error!(
|
||||
"No chip feature activated. You must activate exactly one of the following features: "
|
||||
);
|
||||
|
||||
#[cfg(any(
|
||||
all(feature = "stm32f401", feature = "stm32f405"),
|
||||
all(feature = "stm32f401", feature = "stm32f407"),
|
||||
all(feature = "stm32f401", feature = "stm32f410"),
|
||||
all(feature = "stm32f401", feature = "stm32f411"),
|
||||
all(feature = "stm32f401", feature = "stm32f412"),
|
||||
all(feature = "stm32f401", feature = "stm32f413"),
|
||||
all(feature = "stm32f401", feature = "stm32f415"),
|
||||
all(feature = "stm32f401", feature = "stm32f417"),
|
||||
all(feature = "stm32f401", feature = "stm32f423"),
|
||||
all(feature = "stm32f401", feature = "stm32f427"),
|
||||
all(feature = "stm32f401", feature = "stm32f429"),
|
||||
all(feature = "stm32f401", feature = "stm32f437"),
|
||||
all(feature = "stm32f401", feature = "stm32f439"),
|
||||
all(feature = "stm32f401", feature = "stm32f446"),
|
||||
all(feature = "stm32f401", feature = "stm32f469"),
|
||||
all(feature = "stm32f401", feature = "stm32f479"),
|
||||
all(feature = "stm32f405", feature = "stm32f401"),
|
||||
all(feature = "stm32f405", feature = "stm32f407"),
|
||||
all(feature = "stm32f405", feature = "stm32f410"),
|
||||
all(feature = "stm32f405", feature = "stm32f411"),
|
||||
all(feature = "stm32f405", feature = "stm32f412"),
|
||||
all(feature = "stm32f405", feature = "stm32f413"),
|
||||
all(feature = "stm32f405", feature = "stm32f415"),
|
||||
all(feature = "stm32f405", feature = "stm32f417"),
|
||||
all(feature = "stm32f405", feature = "stm32f423"),
|
||||
all(feature = "stm32f405", feature = "stm32f427"),
|
||||
all(feature = "stm32f405", feature = "stm32f429"),
|
||||
all(feature = "stm32f405", feature = "stm32f437"),
|
||||
all(feature = "stm32f405", feature = "stm32f439"),
|
||||
all(feature = "stm32f405", feature = "stm32f446"),
|
||||
all(feature = "stm32f405", feature = "stm32f469"),
|
||||
all(feature = "stm32f405", feature = "stm32f479"),
|
||||
all(feature = "stm32f407", feature = "stm32f401"),
|
||||
all(feature = "stm32f407", feature = "stm32f405"),
|
||||
all(feature = "stm32f407", feature = "stm32f410"),
|
||||
all(feature = "stm32f407", feature = "stm32f411"),
|
||||
all(feature = "stm32f407", feature = "stm32f412"),
|
||||
all(feature = "stm32f407", feature = "stm32f413"),
|
||||
all(feature = "stm32f407", feature = "stm32f415"),
|
||||
all(feature = "stm32f407", feature = "stm32f417"),
|
||||
all(feature = "stm32f407", feature = "stm32f423"),
|
||||
all(feature = "stm32f407", feature = "stm32f427"),
|
||||
all(feature = "stm32f407", feature = "stm32f429"),
|
||||
all(feature = "stm32f407", feature = "stm32f437"),
|
||||
all(feature = "stm32f407", feature = "stm32f439"),
|
||||
all(feature = "stm32f407", feature = "stm32f446"),
|
||||
all(feature = "stm32f407", feature = "stm32f469"),
|
||||
all(feature = "stm32f407", feature = "stm32f479"),
|
||||
all(feature = "stm32f410", feature = "stm32f401"),
|
||||
all(feature = "stm32f410", feature = "stm32f405"),
|
||||
all(feature = "stm32f410", feature = "stm32f407"),
|
||||
all(feature = "stm32f410", feature = "stm32f411"),
|
||||
all(feature = "stm32f410", feature = "stm32f412"),
|
||||
all(feature = "stm32f410", feature = "stm32f413"),
|
||||
all(feature = "stm32f410", feature = "stm32f415"),
|
||||
all(feature = "stm32f410", feature = "stm32f417"),
|
||||
all(feature = "stm32f410", feature = "stm32f423"),
|
||||
all(feature = "stm32f410", feature = "stm32f427"),
|
||||
all(feature = "stm32f410", feature = "stm32f429"),
|
||||
all(feature = "stm32f410", feature = "stm32f437"),
|
||||
all(feature = "stm32f410", feature = "stm32f439"),
|
||||
all(feature = "stm32f410", feature = "stm32f446"),
|
||||
all(feature = "stm32f410", feature = "stm32f469"),
|
||||
all(feature = "stm32f410", feature = "stm32f479"),
|
||||
all(feature = "stm32f411", feature = "stm32f401"),
|
||||
all(feature = "stm32f411", feature = "stm32f405"),
|
||||
all(feature = "stm32f411", feature = "stm32f407"),
|
||||
all(feature = "stm32f411", feature = "stm32f410"),
|
||||
all(feature = "stm32f411", feature = "stm32f412"),
|
||||
all(feature = "stm32f411", feature = "stm32f413"),
|
||||
all(feature = "stm32f411", feature = "stm32f415"),
|
||||
all(feature = "stm32f411", feature = "stm32f417"),
|
||||
all(feature = "stm32f411", feature = "stm32f423"),
|
||||
all(feature = "stm32f411", feature = "stm32f427"),
|
||||
all(feature = "stm32f411", feature = "stm32f429"),
|
||||
all(feature = "stm32f411", feature = "stm32f437"),
|
||||
all(feature = "stm32f411", feature = "stm32f439"),
|
||||
all(feature = "stm32f411", feature = "stm32f446"),
|
||||
all(feature = "stm32f411", feature = "stm32f469"),
|
||||
all(feature = "stm32f411", feature = "stm32f479"),
|
||||
all(feature = "stm32f412", feature = "stm32f401"),
|
||||
all(feature = "stm32f412", feature = "stm32f405"),
|
||||
all(feature = "stm32f412", feature = "stm32f407"),
|
||||
all(feature = "stm32f412", feature = "stm32f410"),
|
||||
all(feature = "stm32f412", feature = "stm32f411"),
|
||||
all(feature = "stm32f412", feature = "stm32f413"),
|
||||
all(feature = "stm32f412", feature = "stm32f415"),
|
||||
all(feature = "stm32f412", feature = "stm32f417"),
|
||||
all(feature = "stm32f412", feature = "stm32f423"),
|
||||
all(feature = "stm32f412", feature = "stm32f427"),
|
||||
all(feature = "stm32f412", feature = "stm32f429"),
|
||||
all(feature = "stm32f412", feature = "stm32f437"),
|
||||
all(feature = "stm32f412", feature = "stm32f439"),
|
||||
all(feature = "stm32f412", feature = "stm32f446"),
|
||||
all(feature = "stm32f412", feature = "stm32f469"),
|
||||
all(feature = "stm32f412", feature = "stm32f479"),
|
||||
all(feature = "stm32f413", feature = "stm32f401"),
|
||||
all(feature = "stm32f413", feature = "stm32f405"),
|
||||
all(feature = "stm32f413", feature = "stm32f407"),
|
||||
all(feature = "stm32f413", feature = "stm32f410"),
|
||||
all(feature = "stm32f413", feature = "stm32f411"),
|
||||
all(feature = "stm32f413", feature = "stm32f412"),
|
||||
all(feature = "stm32f413", feature = "stm32f415"),
|
||||
all(feature = "stm32f413", feature = "stm32f417"),
|
||||
all(feature = "stm32f413", feature = "stm32f423"),
|
||||
all(feature = "stm32f413", feature = "stm32f427"),
|
||||
all(feature = "stm32f413", feature = "stm32f429"),
|
||||
all(feature = "stm32f413", feature = "stm32f437"),
|
||||
all(feature = "stm32f413", feature = "stm32f439"),
|
||||
all(feature = "stm32f413", feature = "stm32f446"),
|
||||
all(feature = "stm32f413", feature = "stm32f469"),
|
||||
all(feature = "stm32f413", feature = "stm32f479"),
|
||||
all(feature = "stm32f415", feature = "stm32f401"),
|
||||
all(feature = "stm32f415", feature = "stm32f405"),
|
||||
all(feature = "stm32f415", feature = "stm32f407"),
|
||||
all(feature = "stm32f415", feature = "stm32f410"),
|
||||
all(feature = "stm32f415", feature = "stm32f411"),
|
||||
all(feature = "stm32f415", feature = "stm32f412"),
|
||||
all(feature = "stm32f415", feature = "stm32f413"),
|
||||
all(feature = "stm32f415", feature = "stm32f417"),
|
||||
all(feature = "stm32f415", feature = "stm32f423"),
|
||||
all(feature = "stm32f415", feature = "stm32f427"),
|
||||
all(feature = "stm32f415", feature = "stm32f429"),
|
||||
all(feature = "stm32f415", feature = "stm32f437"),
|
||||
all(feature = "stm32f415", feature = "stm32f439"),
|
||||
all(feature = "stm32f415", feature = "stm32f446"),
|
||||
all(feature = "stm32f415", feature = "stm32f469"),
|
||||
all(feature = "stm32f415", feature = "stm32f479"),
|
||||
all(feature = "stm32f417", feature = "stm32f401"),
|
||||
all(feature = "stm32f417", feature = "stm32f405"),
|
||||
all(feature = "stm32f417", feature = "stm32f407"),
|
||||
all(feature = "stm32f417", feature = "stm32f410"),
|
||||
all(feature = "stm32f417", feature = "stm32f411"),
|
||||
all(feature = "stm32f417", feature = "stm32f412"),
|
||||
all(feature = "stm32f417", feature = "stm32f413"),
|
||||
all(feature = "stm32f417", feature = "stm32f415"),
|
||||
all(feature = "stm32f417", feature = "stm32f423"),
|
||||
all(feature = "stm32f417", feature = "stm32f427"),
|
||||
all(feature = "stm32f417", feature = "stm32f429"),
|
||||
all(feature = "stm32f417", feature = "stm32f437"),
|
||||
all(feature = "stm32f417", feature = "stm32f439"),
|
||||
all(feature = "stm32f417", feature = "stm32f446"),
|
||||
all(feature = "stm32f417", feature = "stm32f469"),
|
||||
all(feature = "stm32f417", feature = "stm32f479"),
|
||||
all(feature = "stm32f423", feature = "stm32f401"),
|
||||
all(feature = "stm32f423", feature = "stm32f405"),
|
||||
all(feature = "stm32f423", feature = "stm32f407"),
|
||||
all(feature = "stm32f423", feature = "stm32f410"),
|
||||
all(feature = "stm32f423", feature = "stm32f411"),
|
||||
all(feature = "stm32f423", feature = "stm32f412"),
|
||||
all(feature = "stm32f423", feature = "stm32f413"),
|
||||
all(feature = "stm32f423", feature = "stm32f415"),
|
||||
all(feature = "stm32f423", feature = "stm32f417"),
|
||||
all(feature = "stm32f423", feature = "stm32f427"),
|
||||
all(feature = "stm32f423", feature = "stm32f429"),
|
||||
all(feature = "stm32f423", feature = "stm32f437"),
|
||||
all(feature = "stm32f423", feature = "stm32f439"),
|
||||
all(feature = "stm32f423", feature = "stm32f446"),
|
||||
all(feature = "stm32f423", feature = "stm32f469"),
|
||||
all(feature = "stm32f423", feature = "stm32f479"),
|
||||
all(feature = "stm32f427", feature = "stm32f401"),
|
||||
all(feature = "stm32f427", feature = "stm32f405"),
|
||||
all(feature = "stm32f427", feature = "stm32f407"),
|
||||
all(feature = "stm32f427", feature = "stm32f410"),
|
||||
all(feature = "stm32f427", feature = "stm32f411"),
|
||||
all(feature = "stm32f427", feature = "stm32f412"),
|
||||
all(feature = "stm32f427", feature = "stm32f413"),
|
||||
all(feature = "stm32f427", feature = "stm32f415"),
|
||||
all(feature = "stm32f427", feature = "stm32f417"),
|
||||
all(feature = "stm32f427", feature = "stm32f423"),
|
||||
all(feature = "stm32f427", feature = "stm32f429"),
|
||||
all(feature = "stm32f427", feature = "stm32f437"),
|
||||
all(feature = "stm32f427", feature = "stm32f439"),
|
||||
all(feature = "stm32f427", feature = "stm32f446"),
|
||||
all(feature = "stm32f427", feature = "stm32f469"),
|
||||
all(feature = "stm32f427", feature = "stm32f479"),
|
||||
all(feature = "stm32f429", feature = "stm32f401"),
|
||||
all(feature = "stm32f429", feature = "stm32f405"),
|
||||
all(feature = "stm32f429", feature = "stm32f407"),
|
||||
all(feature = "stm32f429", feature = "stm32f410"),
|
||||
all(feature = "stm32f429", feature = "stm32f411"),
|
||||
all(feature = "stm32f429", feature = "stm32f412"),
|
||||
all(feature = "stm32f429", feature = "stm32f413"),
|
||||
all(feature = "stm32f429", feature = "stm32f415"),
|
||||
all(feature = "stm32f429", feature = "stm32f417"),
|
||||
all(feature = "stm32f429", feature = "stm32f423"),
|
||||
all(feature = "stm32f429", feature = "stm32f427"),
|
||||
all(feature = "stm32f429", feature = "stm32f437"),
|
||||
all(feature = "stm32f429", feature = "stm32f439"),
|
||||
all(feature = "stm32f429", feature = "stm32f446"),
|
||||
all(feature = "stm32f429", feature = "stm32f469"),
|
||||
all(feature = "stm32f429", feature = "stm32f479"),
|
||||
all(feature = "stm32f437", feature = "stm32f401"),
|
||||
all(feature = "stm32f437", feature = "stm32f405"),
|
||||
all(feature = "stm32f437", feature = "stm32f407"),
|
||||
all(feature = "stm32f437", feature = "stm32f410"),
|
||||
all(feature = "stm32f437", feature = "stm32f411"),
|
||||
all(feature = "stm32f437", feature = "stm32f412"),
|
||||
all(feature = "stm32f437", feature = "stm32f413"),
|
||||
all(feature = "stm32f437", feature = "stm32f415"),
|
||||
all(feature = "stm32f437", feature = "stm32f417"),
|
||||
all(feature = "stm32f437", feature = "stm32f423"),
|
||||
all(feature = "stm32f437", feature = "stm32f427"),
|
||||
all(feature = "stm32f437", feature = "stm32f429"),
|
||||
all(feature = "stm32f437", feature = "stm32f439"),
|
||||
all(feature = "stm32f437", feature = "stm32f446"),
|
||||
all(feature = "stm32f437", feature = "stm32f469"),
|
||||
all(feature = "stm32f437", feature = "stm32f479"),
|
||||
all(feature = "stm32f439", feature = "stm32f401"),
|
||||
all(feature = "stm32f439", feature = "stm32f405"),
|
||||
all(feature = "stm32f439", feature = "stm32f407"),
|
||||
all(feature = "stm32f439", feature = "stm32f410"),
|
||||
all(feature = "stm32f439", feature = "stm32f411"),
|
||||
all(feature = "stm32f439", feature = "stm32f412"),
|
||||
all(feature = "stm32f439", feature = "stm32f413"),
|
||||
all(feature = "stm32f439", feature = "stm32f415"),
|
||||
all(feature = "stm32f439", feature = "stm32f417"),
|
||||
all(feature = "stm32f439", feature = "stm32f423"),
|
||||
all(feature = "stm32f439", feature = "stm32f427"),
|
||||
all(feature = "stm32f439", feature = "stm32f429"),
|
||||
all(feature = "stm32f439", feature = "stm32f437"),
|
||||
all(feature = "stm32f439", feature = "stm32f446"),
|
||||
all(feature = "stm32f439", feature = "stm32f469"),
|
||||
all(feature = "stm32f439", feature = "stm32f479"),
|
||||
all(feature = "stm32f446", feature = "stm32f401"),
|
||||
all(feature = "stm32f446", feature = "stm32f405"),
|
||||
all(feature = "stm32f446", feature = "stm32f407"),
|
||||
all(feature = "stm32f446", feature = "stm32f410"),
|
||||
all(feature = "stm32f446", feature = "stm32f411"),
|
||||
all(feature = "stm32f446", feature = "stm32f412"),
|
||||
all(feature = "stm32f446", feature = "stm32f413"),
|
||||
all(feature = "stm32f446", feature = "stm32f415"),
|
||||
all(feature = "stm32f446", feature = "stm32f417"),
|
||||
all(feature = "stm32f446", feature = "stm32f423"),
|
||||
all(feature = "stm32f446", feature = "stm32f427"),
|
||||
all(feature = "stm32f446", feature = "stm32f429"),
|
||||
all(feature = "stm32f446", feature = "stm32f437"),
|
||||
all(feature = "stm32f446", feature = "stm32f439"),
|
||||
all(feature = "stm32f446", feature = "stm32f469"),
|
||||
all(feature = "stm32f446", feature = "stm32f479"),
|
||||
all(feature = "stm32f469", feature = "stm32f401"),
|
||||
all(feature = "stm32f469", feature = "stm32f405"),
|
||||
all(feature = "stm32f469", feature = "stm32f407"),
|
||||
all(feature = "stm32f469", feature = "stm32f410"),
|
||||
all(feature = "stm32f469", feature = "stm32f411"),
|
||||
all(feature = "stm32f469", feature = "stm32f412"),
|
||||
all(feature = "stm32f469", feature = "stm32f413"),
|
||||
all(feature = "stm32f469", feature = "stm32f415"),
|
||||
all(feature = "stm32f469", feature = "stm32f417"),
|
||||
all(feature = "stm32f469", feature = "stm32f423"),
|
||||
all(feature = "stm32f469", feature = "stm32f427"),
|
||||
all(feature = "stm32f469", feature = "stm32f429"),
|
||||
all(feature = "stm32f469", feature = "stm32f437"),
|
||||
all(feature = "stm32f469", feature = "stm32f439"),
|
||||
all(feature = "stm32f469", feature = "stm32f446"),
|
||||
all(feature = "stm32f469", feature = "stm32f479"),
|
||||
all(feature = "stm32f479", feature = "stm32f401"),
|
||||
all(feature = "stm32f479", feature = "stm32f405"),
|
||||
all(feature = "stm32f479", feature = "stm32f407"),
|
||||
all(feature = "stm32f479", feature = "stm32f410"),
|
||||
all(feature = "stm32f479", feature = "stm32f411"),
|
||||
all(feature = "stm32f479", feature = "stm32f412"),
|
||||
all(feature = "stm32f479", feature = "stm32f413"),
|
||||
all(feature = "stm32f479", feature = "stm32f415"),
|
||||
all(feature = "stm32f479", feature = "stm32f417"),
|
||||
all(feature = "stm32f479", feature = "stm32f423"),
|
||||
all(feature = "stm32f479", feature = "stm32f427"),
|
||||
all(feature = "stm32f479", feature = "stm32f429"),
|
||||
all(feature = "stm32f479", feature = "stm32f437"),
|
||||
all(feature = "stm32f479", feature = "stm32f439"),
|
||||
all(feature = "stm32f479", feature = "stm32f446"),
|
||||
all(feature = "stm32f479", feature = "stm32f469"),
|
||||
))]
|
||||
compile_error!(
|
||||
"Multile chip features activated. You must activate exactly one of the following features: "
|
||||
);
|
||||
|
||||
pub use stm32f4xx_hal as hal;
|
||||
pub use stm32f4xx_hal::stm32 as pac;
|
||||
|
||||
// This mod MUST go first, so that the others see its macros.
|
||||
pub(crate) mod fmt;
|
||||
|
||||
pub mod interrupt;
|
||||
pub mod serial;
|
||||
|
||||
pub use cortex_m_rt::interrupt;
|
224
embassy-stm32f4/src/serial.rs
Normal file
224
embassy-stm32f4/src/serial.rs
Normal file
@ -0,0 +1,224 @@
|
||||
//! Async low power Serial.
|
||||
//!
|
||||
//! The peripheral is autmatically enabled and disabled as required to save power.
|
||||
//! Lowest power consumption can only be guaranteed if the send receive futures
|
||||
//! are dropped correctly (e.g. not using `mem::forget()`).
|
||||
|
||||
use core::future::Future;
|
||||
use core::ptr;
|
||||
use core::sync::atomic::{self, Ordering};
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy::interrupt::OwnedInterrupt;
|
||||
use embassy::util::Signal;
|
||||
use embedded_dma::{StaticReadBuffer, StaticWriteBuffer, WriteBuffer};
|
||||
|
||||
use crate::hal::dma::config::DmaConfig;
|
||||
use crate::hal::dma::traits::{PeriAddress, Stream};
|
||||
use crate::hal::dma::{
|
||||
Channel4, MemoryToPeripheral, PeripheralToMemory, Stream2, Stream7, StreamsTuple, Transfer,
|
||||
};
|
||||
use crate::hal::gpio::gpioa::{PA10, PA9};
|
||||
use crate::hal::gpio::{Alternate, AF7};
|
||||
use crate::hal::prelude::*;
|
||||
use crate::hal::rcc::Clocks;
|
||||
use crate::hal::serial::config::{
|
||||
Config as SerialConfig, DmaConfig as SerialDmaConfig, Parity, StopBits, WordLength,
|
||||
};
|
||||
use crate::hal::serial::{Event as SerialEvent, Serial as HalSerial};
|
||||
use crate::hal::time::Bps;
|
||||
|
||||
use crate::interrupt;
|
||||
|
||||
use crate::pac::Interrupt;
|
||||
use crate::pac::{DMA2, USART1};
|
||||
|
||||
/// Interface to the Serial peripheral
|
||||
pub struct Serial<USART: PeriAddress<MemSize = u8>, TSTREAM: Stream, RSTREAM: Stream> {
|
||||
tx_stream: Option<TSTREAM>,
|
||||
rx_stream: Option<RSTREAM>,
|
||||
usart: Option<USART>,
|
||||
tx_int: interrupt::DMA2_STREAM7Interrupt,
|
||||
rx_int: interrupt::DMA2_STREAM2Interrupt,
|
||||
usart_int: interrupt::USART1Interrupt,
|
||||
}
|
||||
|
||||
struct State {
|
||||
tx_int: Signal<()>,
|
||||
rx_int: Signal<()>,
|
||||
}
|
||||
|
||||
static STATE: State = State {
|
||||
tx_int: Signal::new(),
|
||||
rx_int: Signal::new(),
|
||||
};
|
||||
|
||||
static mut INSTANCE: *const Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> = ptr::null_mut();
|
||||
|
||||
impl Serial<USART1, Stream7<DMA2>, Stream2<DMA2>> {
|
||||
pub fn new(
|
||||
txd: PA9<Alternate<AF7>>,
|
||||
rxd: PA10<Alternate<AF7>>,
|
||||
tx_int: interrupt::DMA2_STREAM7Interrupt,
|
||||
rx_int: interrupt::DMA2_STREAM2Interrupt,
|
||||
usart_int: interrupt::USART1Interrupt,
|
||||
dma: DMA2,
|
||||
usart: USART1,
|
||||
parity: Parity,
|
||||
baudrate: Bps,
|
||||
clocks: Clocks,
|
||||
) -> Self {
|
||||
let mut serial = HalSerial::usart1(
|
||||
usart,
|
||||
(txd, rxd),
|
||||
SerialConfig {
|
||||
baudrate: baudrate,
|
||||
wordlength: WordLength::DataBits8,
|
||||
parity: Parity::ParityNone,
|
||||
stopbits: StopBits::STOP1,
|
||||
dma: SerialDmaConfig::TxRx,
|
||||
},
|
||||
clocks,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
serial.listen(SerialEvent::Idle);
|
||||
// serial.listen(SerialEvent::Txe);
|
||||
|
||||
let (usart, _) = serial.release();
|
||||
|
||||
// Register ISR
|
||||
tx_int.set_handler(Self::on_tx_irq);
|
||||
rx_int.set_handler(Self::on_rx_irq);
|
||||
usart_int.set_handler(Self::on_rx_irq);
|
||||
// usart_int.unpend();
|
||||
// usart_int.enable();
|
||||
|
||||
let streams = StreamsTuple::new(dma);
|
||||
|
||||
Serial {
|
||||
tx_stream: Some(streams.7),
|
||||
rx_stream: Some(streams.2),
|
||||
usart: Some(usart),
|
||||
tx_int: tx_int,
|
||||
rx_int: rx_int,
|
||||
usart_int: usart_int,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn on_tx_irq() {
|
||||
let s = &(*INSTANCE);
|
||||
|
||||
s.tx_int.disable();
|
||||
|
||||
STATE.tx_int.signal(());
|
||||
}
|
||||
|
||||
unsafe fn on_rx_irq() {
|
||||
let s = &(*INSTANCE);
|
||||
|
||||
atomic::compiler_fence(Ordering::Acquire);
|
||||
s.rx_int.disable();
|
||||
s.usart_int.disable();
|
||||
atomic::compiler_fence(Ordering::Release);
|
||||
|
||||
STATE.rx_int.signal(());
|
||||
}
|
||||
|
||||
unsafe fn on_usart_irq() {
|
||||
let s = &(*INSTANCE);
|
||||
|
||||
atomic::compiler_fence(Ordering::Acquire);
|
||||
s.rx_int.disable();
|
||||
s.usart_int.disable();
|
||||
atomic::compiler_fence(Ordering::Release);
|
||||
|
||||
STATE.rx_int.signal(());
|
||||
}
|
||||
|
||||
/// Sends serial data.
|
||||
///
|
||||
/// `tx_buffer` is marked as static as per `embedded-dma` requirements.
|
||||
/// It it safe to use a buffer with a non static lifetime if memory is not
|
||||
/// reused until the future has finished.
|
||||
pub fn send<'a, B: 'a>(&'a mut self, tx_buffer: B) -> impl Future<Output = ()> + 'a
|
||||
where
|
||||
B: StaticWriteBuffer<Word = u8>,
|
||||
{
|
||||
unsafe { INSTANCE = self };
|
||||
|
||||
let tx_stream = self.tx_stream.take().unwrap();
|
||||
let usart = self.usart.take().unwrap();
|
||||
STATE.tx_int.reset();
|
||||
|
||||
async move {
|
||||
let mut tx_transfer = Transfer::init(
|
||||
tx_stream,
|
||||
usart,
|
||||
tx_buffer,
|
||||
None,
|
||||
DmaConfig::default()
|
||||
.transfer_complete_interrupt(true)
|
||||
.memory_increment(true)
|
||||
.double_buffer(false),
|
||||
);
|
||||
|
||||
self.tx_int.unpend();
|
||||
self.tx_int.enable();
|
||||
tx_transfer.start(|_usart| {});
|
||||
|
||||
STATE.tx_int.wait().await;
|
||||
|
||||
let (tx_stream, usart, _buf, _) = tx_transfer.free();
|
||||
self.tx_stream.replace(tx_stream);
|
||||
self.usart.replace(usart);
|
||||
}
|
||||
}
|
||||
|
||||
/// Receives serial data.
|
||||
///
|
||||
/// The future is pending until the buffer is completely filled.
|
||||
/// A common pattern is to use [`stop()`](ReceiveFuture::stop) to cancel
|
||||
/// unfinished transfers after a timeout to prevent lockup when no more data
|
||||
/// is incoming.
|
||||
///
|
||||
/// `rx_buffer` is marked as static as per `embedded-dma` requirements.
|
||||
/// It it safe to use a buffer with a non static lifetime if memory is not
|
||||
/// reused until the future has finished.
|
||||
pub fn receive<'a, B: 'a>(&'a mut self, rx_buffer: B) -> impl Future<Output = B> + 'a
|
||||
where
|
||||
B: StaticWriteBuffer<Word = u8> + Unpin,
|
||||
{
|
||||
unsafe { INSTANCE = self };
|
||||
|
||||
let rx_stream = self.rx_stream.take().unwrap();
|
||||
let usart = self.usart.take().unwrap();
|
||||
STATE.rx_int.reset();
|
||||
|
||||
async move {
|
||||
let mut rx_transfer = Transfer::init(
|
||||
rx_stream,
|
||||
usart,
|
||||
rx_buffer,
|
||||
None,
|
||||
DmaConfig::default()
|
||||
.transfer_complete_interrupt(true)
|
||||
.memory_increment(true)
|
||||
.double_buffer(false),
|
||||
);
|
||||
|
||||
self.rx_int.unpend();
|
||||
self.rx_int.enable();
|
||||
|
||||
rx_transfer.start(|_usart| {});
|
||||
|
||||
STATE.rx_int.wait().await;
|
||||
|
||||
let (rx_stream, usart, buf, _) = rx_transfer.free();
|
||||
self.rx_stream.replace(rx_stream);
|
||||
self.usart.replace(usart);
|
||||
|
||||
buf
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user