stm32f4: implement idle on serial
This commit is contained in:
parent
d1ac703830
commit
556942a6bf
@ -36,6 +36,7 @@ defmt = { version = "0.2.0", optional = true }
|
|||||||
log = { version = "0.4.11", optional = true }
|
log = { version = "0.4.11", optional = true }
|
||||||
cortex-m-rt = "0.6.13"
|
cortex-m-rt = "0.6.13"
|
||||||
cortex-m = "0.7.1"
|
cortex-m = "0.7.1"
|
||||||
|
futures = { version = "0.3.5", default-features = false, features = ["async-await"] }
|
||||||
embedded-hal = { version = "0.2.4" }
|
embedded-hal = { version = "0.2.4" }
|
||||||
embedded-dma = { version = "0.1.2" }
|
embedded-dma = { version = "0.1.2" }
|
||||||
stm32f4xx-hal = { version = "0.8.3", features = ["rt", "can"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"}
|
stm32f4xx-hal = { version = "0.8.3", features = ["rt", "can"], git = "https://github.com/stm32-rs/stm32f4xx-hal.git"}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
use futures::{select_biased, FutureExt};
|
||||||
|
|
||||||
use embassy::interrupt::Interrupt;
|
use embassy::interrupt::Interrupt;
|
||||||
use embassy::traits::uart::{Error, Uart};
|
use embassy::traits::uart::{Error, Uart};
|
||||||
use embassy::util::InterruptFuture;
|
use embassy::util::InterruptFuture;
|
||||||
@ -19,7 +21,7 @@ use crate::hal::{
|
|||||||
rcc::Clocks,
|
rcc::Clocks,
|
||||||
serial,
|
serial,
|
||||||
serial::config::{Config as SerialConfig, DmaConfig as SerialDmaConfig},
|
serial::config::{Config as SerialConfig, DmaConfig as SerialDmaConfig},
|
||||||
serial::{Event as SerialEvent, Pins, Serial as HalSerial},
|
serial::{Event as SerialEvent, Pins},
|
||||||
};
|
};
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::pac;
|
use crate::pac;
|
||||||
@ -29,14 +31,14 @@ pub struct Serial<
|
|||||||
USART: PeriAddress<MemSize = u8> + WithInterrupt,
|
USART: PeriAddress<MemSize = u8> + WithInterrupt,
|
||||||
TSTREAM: Stream + WithInterrupt,
|
TSTREAM: Stream + WithInterrupt,
|
||||||
RSTREAM: Stream + WithInterrupt,
|
RSTREAM: Stream + WithInterrupt,
|
||||||
CHANNEL: dma::traits::Channel,
|
CHANNEL: Channel,
|
||||||
> {
|
> {
|
||||||
tx_stream: Option<TSTREAM>,
|
tx_stream: Option<TSTREAM>,
|
||||||
rx_stream: Option<RSTREAM>,
|
rx_stream: Option<RSTREAM>,
|
||||||
usart: Option<USART>,
|
usart: Option<USART>,
|
||||||
tx_int: TSTREAM::Interrupt,
|
tx_int: TSTREAM::Interrupt,
|
||||||
rx_int: RSTREAM::Interrupt,
|
rx_int: RSTREAM::Interrupt,
|
||||||
_usart_int: USART::Interrupt,
|
usart_int: USART::Interrupt,
|
||||||
channel: PhantomData<CHANNEL>,
|
channel: PhantomData<CHANNEL>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +70,10 @@ where
|
|||||||
PINS: Pins<USART>,
|
PINS: Pins<USART>,
|
||||||
{
|
{
|
||||||
config.dma = SerialDmaConfig::TxRx;
|
config.dma = SerialDmaConfig::TxRx;
|
||||||
let mut serial = HalSerial::new(usart, pins, config, clocks).unwrap();
|
|
||||||
|
|
||||||
serial.listen(SerialEvent::Idle);
|
let (usart, _) = serial::Serial::new(usart, pins, config, clocks)
|
||||||
// serial.listen(SerialEvent::Txe);
|
.unwrap()
|
||||||
|
.release();
|
||||||
let (usart, _) = serial.release();
|
|
||||||
|
|
||||||
let (tx_stream, rx_stream) = streams;
|
let (tx_stream, rx_stream) = streams;
|
||||||
|
|
||||||
@ -83,8 +83,8 @@ where
|
|||||||
usart: Some(usart),
|
usart: Some(usart),
|
||||||
tx_int: tx_int,
|
tx_int: tx_int,
|
||||||
rx_int: rx_int,
|
rx_int: rx_int,
|
||||||
_usart_int: usart_int,
|
usart_int: usart_int,
|
||||||
channel: core::marker::PhantomData,
|
channel: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,10 +127,10 @@ where
|
|||||||
let fut = InterruptFuture::new(&mut self.tx_int);
|
let fut = InterruptFuture::new(&mut self.tx_int);
|
||||||
|
|
||||||
tx_transfer.start(|_usart| {});
|
tx_transfer.start(|_usart| {});
|
||||||
|
|
||||||
fut.await;
|
fut.await;
|
||||||
|
|
||||||
let (tx_stream, usart, _buf, _) = tx_transfer.free();
|
let (tx_stream, usart, _buf, _) = tx_transfer.free();
|
||||||
|
|
||||||
self.tx_stream.replace(tx_stream);
|
self.tx_stream.replace(tx_stream);
|
||||||
self.usart.replace(usart);
|
self.usart.replace(usart);
|
||||||
|
|
||||||
@ -151,6 +151,15 @@ where
|
|||||||
let usart = self.usart.take().unwrap();
|
let usart = self.usart.take().unwrap();
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
|
unsafe {
|
||||||
|
/* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */
|
||||||
|
(*USART::ptr()).cr1.modify(|_, w| w.idleie().set_bit());
|
||||||
|
|
||||||
|
/* __HAL_UART_CLEAR_IDLEFLAG(&uart->UartHandle); */
|
||||||
|
(*USART::ptr()).sr.read();
|
||||||
|
(*USART::ptr()).dr.read();
|
||||||
|
};
|
||||||
|
|
||||||
let mut rx_transfer = Transfer::init(
|
let mut rx_transfer = Transfer::init(
|
||||||
rx_stream,
|
rx_stream,
|
||||||
usart,
|
usart,
|
||||||
@ -163,11 +172,20 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
let fut = InterruptFuture::new(&mut self.rx_int);
|
let fut = InterruptFuture::new(&mut self.rx_int);
|
||||||
|
let fut_idle = InterruptFuture::new(&mut self.usart_int);
|
||||||
|
|
||||||
rx_transfer.start(|_usart| {});
|
rx_transfer.start(|_usart| {});
|
||||||
fut.await;
|
|
||||||
|
select_biased! {
|
||||||
|
() = fut.fuse() => {},
|
||||||
|
() = fut_idle.fuse() => {},
|
||||||
|
}
|
||||||
|
|
||||||
let (rx_stream, usart, _, _) = rx_transfer.free();
|
let (rx_stream, usart, _, _) = rx_transfer.free();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
|
||||||
|
}
|
||||||
self.rx_stream.replace(rx_stream);
|
self.rx_stream.replace(rx_stream);
|
||||||
self.usart.replace(usart);
|
self.usart.replace(usart);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user