stm32f4: implement idle on serial
This commit is contained in:
parent
d1ac703830
commit
556942a6bf
2 changed files with 31 additions and 12 deletions
|
@ -36,6 +36,7 @@ defmt = { version = "0.2.0", optional = true }
|
|||
log = { version = "0.4.11", optional = true }
|
||||
cortex-m-rt = "0.6.13"
|
||||
cortex-m = "0.7.1"
|
||||
futures = { version = "0.3.5", default-features = false, features = ["async-await"] }
|
||||
embedded-hal = { version = "0.2.4" }
|
||||
embedded-dma = { version = "0.1.2" }
|
||||
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::marker::PhantomData;
|
||||
|
||||
use futures::{select_biased, FutureExt};
|
||||
|
||||
use embassy::interrupt::Interrupt;
|
||||
use embassy::traits::uart::{Error, Uart};
|
||||
use embassy::util::InterruptFuture;
|
||||
|
@ -19,7 +21,7 @@ use crate::hal::{
|
|||
rcc::Clocks,
|
||||
serial,
|
||||
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::pac;
|
||||
|
@ -29,14 +31,14 @@ pub struct Serial<
|
|||
USART: PeriAddress<MemSize = u8> + WithInterrupt,
|
||||
TSTREAM: Stream + WithInterrupt,
|
||||
RSTREAM: Stream + WithInterrupt,
|
||||
CHANNEL: dma::traits::Channel,
|
||||
CHANNEL: Channel,
|
||||
> {
|
||||
tx_stream: Option<TSTREAM>,
|
||||
rx_stream: Option<RSTREAM>,
|
||||
usart: Option<USART>,
|
||||
tx_int: TSTREAM::Interrupt,
|
||||
rx_int: RSTREAM::Interrupt,
|
||||
_usart_int: USART::Interrupt,
|
||||
usart_int: USART::Interrupt,
|
||||
channel: PhantomData<CHANNEL>,
|
||||
}
|
||||
|
||||
|
@ -68,12 +70,10 @@ where
|
|||
PINS: Pins<USART>,
|
||||
{
|
||||
config.dma = SerialDmaConfig::TxRx;
|
||||
let mut serial = HalSerial::new(usart, pins, config, clocks).unwrap();
|
||||
|
||||
serial.listen(SerialEvent::Idle);
|
||||
// serial.listen(SerialEvent::Txe);
|
||||
|
||||
let (usart, _) = serial.release();
|
||||
let (usart, _) = serial::Serial::new(usart, pins, config, clocks)
|
||||
.unwrap()
|
||||
.release();
|
||||
|
||||
let (tx_stream, rx_stream) = streams;
|
||||
|
||||
|
@ -83,8 +83,8 @@ where
|
|||
usart: Some(usart),
|
||||
tx_int: tx_int,
|
||||
rx_int: rx_int,
|
||||
_usart_int: usart_int,
|
||||
channel: core::marker::PhantomData,
|
||||
usart_int: usart_int,
|
||||
channel: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,10 +127,10 @@ where
|
|||
let fut = InterruptFuture::new(&mut self.tx_int);
|
||||
|
||||
tx_transfer.start(|_usart| {});
|
||||
|
||||
fut.await;
|
||||
|
||||
let (tx_stream, usart, _buf, _) = tx_transfer.free();
|
||||
|
||||
self.tx_stream.replace(tx_stream);
|
||||
self.usart.replace(usart);
|
||||
|
||||
|
@ -151,6 +151,15 @@ where
|
|||
let usart = self.usart.take().unwrap();
|
||||
|
||||
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(
|
||||
rx_stream,
|
||||
usart,
|
||||
|
@ -163,11 +172,20 @@ where
|
|||
);
|
||||
|
||||
let fut = InterruptFuture::new(&mut self.rx_int);
|
||||
let fut_idle = InterruptFuture::new(&mut self.usart_int);
|
||||
|
||||
rx_transfer.start(|_usart| {});
|
||||
fut.await;
|
||||
|
||||
select_biased! {
|
||||
() = fut.fuse() => {},
|
||||
() = fut_idle.fuse() => {},
|
||||
}
|
||||
|
||||
let (rx_stream, usart, _, _) = rx_transfer.free();
|
||||
|
||||
unsafe {
|
||||
(*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
|
||||
}
|
||||
self.rx_stream.replace(rx_stream);
|
||||
self.usart.replace(usart);
|
||||
|
||||
|
|
Loading…
Reference in a new issue