From 556942a6bf0933921f33bfcb0155fbabf33b59c6 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 20 Mar 2021 23:51:24 -0500 Subject: [PATCH] stm32f4: implement idle on serial --- embassy-stm32f4/Cargo.toml | 1 + embassy-stm32f4/src/serial.rs | 42 +++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/embassy-stm32f4/Cargo.toml b/embassy-stm32f4/Cargo.toml index ae3273d6..c132d7c9 100644 --- a/embassy-stm32f4/Cargo.toml +++ b/embassy-stm32f4/Cargo.toml @@ -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"} diff --git a/embassy-stm32f4/src/serial.rs b/embassy-stm32f4/src/serial.rs index 381e0f5e..bed89288 100644 --- a/embassy-stm32f4/src/serial.rs +++ b/embassy-stm32f4/src/serial.rs @@ -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 + WithInterrupt, TSTREAM: Stream + WithInterrupt, RSTREAM: Stream + WithInterrupt, - CHANNEL: dma::traits::Channel, + CHANNEL: Channel, > { tx_stream: Option, rx_stream: Option, usart: Option, tx_int: TSTREAM::Interrupt, rx_int: RSTREAM::Interrupt, - _usart_int: USART::Interrupt, + usart_int: USART::Interrupt, channel: PhantomData, } @@ -68,12 +70,10 @@ where PINS: Pins, { 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);