Skip to content

Commit 5928819

Browse files
bors[bot]rursprung
andauthored
Merge #556
556: offer `clear_idle_interrupt` from `serial::Rx` in DMA `Transfer` r=burrbull a=rursprung please see the individual commit messages for further details. i've tested this on an STM32F401. this solves #550. Co-authored-by: Ralph Ursprung <[email protected]>
2 parents 9d21215 + 8296969 commit 5928819

File tree

4 files changed

+61
-19
lines changed

4 files changed

+61
-19
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
5454
- Added rtic-usart-shell example [#551]
5555
- Added rtic-usart-shell-ssd1306 example [#551]
5656
- Added rtic-usb-cdc-echo example [#553]
57+
- Add possibility to clear a Serial `Rx` idle interrupt from a DMA `Transfer` [#556]
5758

5859

5960
[#481]: https://github.com/stm32-rs/stm32f4xx-hal/pull/481
@@ -79,6 +80,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
7980
[#553]: https://github.com/stm32-rs/stm32f4xx-hal/pull/553
8081
[#554]: https://github.com/stm32-rs/stm32f4xx-hal/pull/554
8182
[#555]: https://github.com/stm32-rs/stm32f4xx-hal/pull/555
83+
[#556]: https://github.com/stm32-rs/stm32f4xx-hal/pull/556
8284

8385
## [v0.13.2] - 2022-05-16
8486

src/dma/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::pac::RCC;
2121
use crate::{pac, rcc};
2222

2323
pub mod traits;
24+
use crate::serial::RxISR;
2425
use traits::{
2526
sealed::{Bits, Sealed},
2627
Channel, DMASet, Direction, Instance, PeriAddress, SafePeripheralRead, Stream, StreamISR,
@@ -1014,6 +1015,20 @@ where
10141015
}
10151016
}
10161017

1018+
impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF>
1019+
Transfer<STREAM, CHANNEL, PERIPHERAL, PeripheralToMemory, BUF>
1020+
where
1021+
STREAM: Stream,
1022+
ChannelX<CHANNEL>: Channel,
1023+
PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, PeripheralToMemory> + RxISR,
1024+
BUF: ReadBuffer<Word = <PERIPHERAL as PeriAddress>::MemSize>,
1025+
{
1026+
/// Clear idle line interrupt flag
1027+
pub fn clear_idle_interrupt(&self) {
1028+
self.peripheral.clear_idle_interrupt();
1029+
}
1030+
}
1031+
10171032
impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF>
10181033
Transfer<STREAM, CHANNEL, PERIPHERAL, PeripheralToMemory, BUF>
10191034
where

src/prelude.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ pub use crate::qei::QeiExt as _stm32f4xx_hal_QeiExt;
6868
pub use crate::rcc::RccExt as _stm32f4xx_hal_rcc_RccExt;
6969
#[cfg(all(feature = "device-selected", feature = "rng"))]
7070
pub use crate::rng::RngExt as _stm32f4xx_hal_rng_RngExt;
71+
pub use crate::serial::RxISR as _stm32f4xx_hal_serial_RxISR;
7172
pub use crate::serial::SerialExt as _stm32f4xx_hal_serial_SerialExt;
73+
pub use crate::serial::TxISR as _stm32f4xx_hal_serial_TxISR;
7274
pub use crate::spi::SpiExt as _stm32f4xx_hal_spi_SpiExt;
7375
pub use crate::syscfg::SysCfgExt as _stm32f4xx_hal_syscfg_SysCfgExt;
7476
pub use crate::time::U32Ext as _stm32f4xx_hal_time_U32Ext;

src/serial.rs

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -262,19 +262,33 @@ impl<USART: Instance, WORD> Rx<USART, WORD> {
262262
pub fn unlisten_idle(&mut self) {
263263
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit()) }
264264
}
265+
}
266+
267+
/// Trait for [`Rx`] interrupt handling.
268+
pub trait RxISR {
269+
/// Return true if the line idle status is set
270+
fn is_idle(&self) -> bool;
271+
272+
/// Return true if the rx register is not empty (and can be read)
273+
fn is_rx_not_empty(&self) -> bool;
274+
275+
/// Clear idle line interrupt flag
276+
fn clear_idle_interrupt(&self);
277+
}
265278

279+
impl<USART: Instance, WORD> RxISR for Rx<USART, WORD> {
266280
/// Return true if the line idle status is set
267-
pub fn is_idle(&self) -> bool {
281+
fn is_idle(&self) -> bool {
268282
unsafe { (*USART::ptr()).sr.read().idle().bit_is_set() }
269283
}
270284

271285
/// Return true if the rx register is not empty (and can be read)
272-
pub fn is_rx_not_empty(&self) -> bool {
286+
fn is_rx_not_empty(&self) -> bool {
273287
unsafe { (*USART::ptr()).sr.read().rxne().bit_is_set() }
274288
}
275289

276290
/// Clear idle line interrupt flag
277-
pub fn clear_idle_interrupt(&self) {
291+
fn clear_idle_interrupt(&self) {
278292
unsafe {
279293
let _ = (*USART::ptr()).sr.read();
280294
let _ = (*USART::ptr()).dr.read();
@@ -302,9 +316,17 @@ impl<USART: Instance, WORD> Tx<USART, WORD> {
302316
pub fn unlisten(&mut self) {
303317
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.txeie().clear_bit()) }
304318
}
319+
}
320+
321+
/// Trait for [`Tx`] interrupt handling.
322+
pub trait TxISR {
323+
/// Return true if the tx register is empty (and can accept data)
324+
fn is_tx_empty(&self) -> bool;
325+
}
305326

327+
impl<USART: Instance, WORD> TxISR for Tx<USART, WORD> {
306328
/// Return true if the tx register is empty (and can accept data)
307-
pub fn is_tx_empty(&self) -> bool {
329+
fn is_tx_empty(&self) -> bool {
308330
unsafe { (*USART::ptr()).sr.read().txe().bit_is_set() }
309331
}
310332
}
@@ -713,31 +735,32 @@ impl<USART: Instance, PINS, WORD> Serial<USART, PINS, WORD> {
713735
}
714736
}
715737

716-
/// Return true if the line idle status is set
717-
pub fn is_idle(&self) -> bool {
718-
unsafe { (*USART::ptr()).sr.read().idle().bit_is_set() }
738+
pub fn split(self) -> (Tx<USART, WORD>, Rx<USART, WORD>) {
739+
(self.tx, self.rx)
719740
}
741+
}
720742

721-
/// Return true if the tx register is empty (and can accept data)
722-
pub fn is_tx_empty(&self) -> bool {
723-
unsafe { (*USART::ptr()).sr.read().txe().bit_is_set() }
743+
impl<USART: Instance, PINS, WORD> RxISR for Serial<USART, PINS, WORD> {
744+
/// Return true if the line idle status is set
745+
fn is_idle(&self) -> bool {
746+
self.rx.is_idle()
724747
}
725748

726749
/// Return true if the rx register is not empty (and can be read)
727-
pub fn is_rx_not_empty(&self) -> bool {
728-
unsafe { (*USART::ptr()).sr.read().rxne().bit_is_set() }
750+
fn is_rx_not_empty(&self) -> bool {
751+
self.rx.is_rx_not_empty()
729752
}
730753

731754
/// Clear idle line interrupt flag
732-
pub fn clear_idle_interrupt(&self) {
733-
unsafe {
734-
let _ = (*USART::ptr()).sr.read();
735-
let _ = (*USART::ptr()).dr.read();
736-
}
755+
fn clear_idle_interrupt(&self) {
756+
self.rx.clear_idle_interrupt();
737757
}
758+
}
738759

739-
pub fn split(self) -> (Tx<USART, WORD>, Rx<USART, WORD>) {
740-
(self.tx, self.rx)
760+
impl<USART: Instance, PINS, WORD> TxISR for Serial<USART, PINS, WORD> {
761+
/// Return true if the tx register is empty (and can accept data)
762+
fn is_tx_empty(&self) -> bool {
763+
self.tx.is_tx_empty()
741764
}
742765
}
743766

0 commit comments

Comments
 (0)