Skip to content

Commit

Permalink
Merge #556
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
bors[bot] and rursprung authored Dec 9, 2022
2 parents 9d21215 + 8296969 commit 5928819
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 19 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added rtic-usart-shell example [#551]
- Added rtic-usart-shell-ssd1306 example [#551]
- Added rtic-usb-cdc-echo example [#553]
- Add possibility to clear a Serial `Rx` idle interrupt from a DMA `Transfer` [#556]


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

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

Expand Down
15 changes: 15 additions & 0 deletions src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::pac::RCC;
use crate::{pac, rcc};

pub mod traits;
use crate::serial::RxISR;
use traits::{
sealed::{Bits, Sealed},
Channel, DMASet, Direction, Instance, PeriAddress, SafePeripheralRead, Stream, StreamISR,
Expand Down Expand Up @@ -1014,6 +1015,20 @@ where
}
}

impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF>
Transfer<STREAM, CHANNEL, PERIPHERAL, PeripheralToMemory, BUF>
where
STREAM: Stream,
ChannelX<CHANNEL>: Channel,
PERIPHERAL: PeriAddress + DMASet<STREAM, CHANNEL, PeripheralToMemory> + RxISR,
BUF: ReadBuffer<Word = <PERIPHERAL as PeriAddress>::MemSize>,
{
/// Clear idle line interrupt flag
pub fn clear_idle_interrupt(&self) {
self.peripheral.clear_idle_interrupt();
}
}

impl<STREAM, const CHANNEL: u8, PERIPHERAL, BUF>
Transfer<STREAM, CHANNEL, PERIPHERAL, PeripheralToMemory, BUF>
where
Expand Down
2 changes: 2 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ pub use crate::qei::QeiExt as _stm32f4xx_hal_QeiExt;
pub use crate::rcc::RccExt as _stm32f4xx_hal_rcc_RccExt;
#[cfg(all(feature = "device-selected", feature = "rng"))]
pub use crate::rng::RngExt as _stm32f4xx_hal_rng_RngExt;
pub use crate::serial::RxISR as _stm32f4xx_hal_serial_RxISR;
pub use crate::serial::SerialExt as _stm32f4xx_hal_serial_SerialExt;
pub use crate::serial::TxISR as _stm32f4xx_hal_serial_TxISR;
pub use crate::spi::SpiExt as _stm32f4xx_hal_spi_SpiExt;
pub use crate::syscfg::SysCfgExt as _stm32f4xx_hal_syscfg_SysCfgExt;
pub use crate::time::U32Ext as _stm32f4xx_hal_time_U32Ext;
Expand Down
61 changes: 42 additions & 19 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,19 +262,33 @@ impl<USART: Instance, WORD> Rx<USART, WORD> {
pub fn unlisten_idle(&mut self) {
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit()) }
}
}

/// Trait for [`Rx`] interrupt handling.
pub trait RxISR {
/// Return true if the line idle status is set
fn is_idle(&self) -> bool;

/// Return true if the rx register is not empty (and can be read)
fn is_rx_not_empty(&self) -> bool;

/// Clear idle line interrupt flag
fn clear_idle_interrupt(&self);
}

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

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

/// Clear idle line interrupt flag
pub fn clear_idle_interrupt(&self) {
fn clear_idle_interrupt(&self) {
unsafe {
let _ = (*USART::ptr()).sr.read();
let _ = (*USART::ptr()).dr.read();
Expand Down Expand Up @@ -302,9 +316,17 @@ impl<USART: Instance, WORD> Tx<USART, WORD> {
pub fn unlisten(&mut self) {
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.txeie().clear_bit()) }
}
}

/// Trait for [`Tx`] interrupt handling.
pub trait TxISR {
/// Return true if the tx register is empty (and can accept data)
fn is_tx_empty(&self) -> bool;
}

impl<USART: Instance, WORD> TxISR for Tx<USART, WORD> {
/// Return true if the tx register is empty (and can accept data)
pub fn is_tx_empty(&self) -> bool {
fn is_tx_empty(&self) -> bool {
unsafe { (*USART::ptr()).sr.read().txe().bit_is_set() }
}
}
Expand Down Expand Up @@ -713,31 +735,32 @@ impl<USART: Instance, PINS, WORD> Serial<USART, PINS, WORD> {
}
}

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

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

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

/// Clear idle line interrupt flag
pub fn clear_idle_interrupt(&self) {
unsafe {
let _ = (*USART::ptr()).sr.read();
let _ = (*USART::ptr()).dr.read();
}
fn clear_idle_interrupt(&self) {
self.rx.clear_idle_interrupt();
}
}

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

Expand Down

0 comments on commit 5928819

Please sign in to comment.