Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

- use `Listen` for `Rx/Tx`

## [v0.23.0] - 2025-09-22

- Implement `embedded_hal::i2c::I2c` for `I2cMasterDma` [#838]
Expand Down
2 changes: 1 addition & 1 deletion examples/rtic-serial-dma-rx-idle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ mod app {
.unwrap();

// Listen UART IDLE event, which will be call USART1 interrupt
rx.listen_idle();
rx.listen(serial::RxEvent::Idle);

let dma2 = StreamsTuple::new(dp.DMA2, &mut rcc);

Expand Down
2 changes: 1 addition & 1 deletion examples/uart-dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ fn main() -> ! {

let (tx, mut rx) = uart3.split();

rx.listen_idle();
rx.listen(serial::RxEvent::Idle);

cortex_m::interrupt::free(|cs| *G_UART3_TX.borrow(cs).borrow_mut() = Some(tx));

Expand Down
18 changes: 6 additions & 12 deletions src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,18 +456,12 @@ where
type Event = DmaEvent;

#[inline(always)]
fn listen(&mut self, interrupts: impl Into<BitFlags<DmaEvent>>) {
self.listen_event(None, Some(interrupts.into()));
}

#[inline(always)]
fn listen_only(&mut self, interrupts: impl Into<BitFlags<DmaEvent>>) {
self.listen_event(Some(BitFlags::ALL), Some(interrupts.into()));
}

#[inline(always)]
fn unlisten(&mut self, interrupts: impl Into<BitFlags<DmaEvent>>) {
self.listen_event(Some(interrupts.into()), None);
fn listen_event(
&mut self,
disable: Option<BitFlags<Self::Event>>,
enable: Option<BitFlags<Self::Event>>,
) {
self.listen_event(disable, enable)
}
}

Expand Down
21 changes: 18 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,35 @@ pub trait Listen {
/// Enum of bit flags associated with events
type Event: BitFlag;

#[doc(hidden)]
fn listen_event(
&mut self,
disable: Option<BitFlags<Self::Event>>,
enable: Option<BitFlags<Self::Event>>,
);

/// Start listening for `Event`s
///
/// Note, you will also have to enable the appropriate interrupt in the NVIC to start
/// receiving events.
fn listen(&mut self, event: impl Into<BitFlags<Self::Event>>);
#[inline(always)]
fn listen(&mut self, event: impl Into<BitFlags<Self::Event>>) {
self.listen_event(None, Some(event.into()));
}

/// Start listening for `Event`s, stop all other
///
/// Note, you will also have to enable the appropriate interrupt in the NVIC to start
/// receiving events.
fn listen_only(&mut self, event: impl Into<BitFlags<Self::Event>>);
#[inline(always)]
fn listen_only(&mut self, event: impl Into<BitFlags<Self::Event>>) {
self.listen_event(Some(BitFlags::ALL), Some(event.into()));
}

/// Stop listening for `Event`s
fn unlisten(&mut self, event: impl Into<BitFlags<Self::Event>>);
fn unlisten(&mut self, event: impl Into<BitFlags<Self::Event>>) {
self.listen_event(Some(event.into()), None);
}

/// Start listening all `Event`s
#[inline(always)]
Expand Down
2 changes: 0 additions & 2 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,8 @@ pub use crate::serial::dma::SerialHandleIT as _stm32f4xx_hal_serial_dma_SerialHa
pub use crate::serial::dma::SerialReadDMA as _stm32f4xx_hal_serial_dma_SerialReadDMA;
pub use crate::serial::dma::SerialWriteDMA as _stm32f4xx_hal_serial_dma_SerialWriteDMA;
pub use crate::serial::RxISR as _stm32f4xx_hal_serial_RxISR;
pub use crate::serial::RxListen as _stm32f4xx_hal_serial_RxListen;
pub use crate::serial::SerialExt as _stm32f4xx_hal_serial_SerialExt;
pub use crate::serial::TxISR as _stm32f4xx_hal_serial_TxISR;
pub use crate::serial::TxListen as _stm32f4xx_hal_serial_TxListen;
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
125 changes: 54 additions & 71 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mod hal_02;
mod hal_1;

mod uart_impls;
use uart_impls::RegisterBlockImpl;
use uart_impls::RBExt;

use crate::gpio::{self, PushPull};

Expand Down Expand Up @@ -77,6 +77,32 @@ pub enum Event {
ParityError = 1 << 8,
}

/// UART interrupt events
#[enumflags2::bitflags]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(u16)]
pub enum RxEvent {
/// IDLE interrupt enable
Idle = 1 << 4,
/// RXNE interrupt enable
RxNotEmpty = 1 << 5,
/// PE interrupt enable
ParityError = 1 << 8,
}

/// UART interrupt events
#[enumflags2::bitflags]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(u16)]
pub enum TxEvent {
/// Transmission complete interrupt enable
TransmissionComplete = 1 << 6,
/// TXE interrupt enable
TxEmpty = 1 << 7,
}

/// UART/USART status flags
#[enumflags2::bitflags]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
Expand Down Expand Up @@ -128,7 +154,7 @@ pub use gpio::alt::SerialAsync as CommonPins;
// Implemented by all USART/UART instances
pub trait Instance:
crate::Sealed
+ crate::Ptr<RB: RegisterBlockImpl>
+ crate::Ptr<RB: RBExt>
+ crate::Steal
+ core::ops::Deref<Target = Self::RB>
+ rcc::Enable
Expand Down Expand Up @@ -161,37 +187,30 @@ pub trait TxISR {
fn is_tx_empty(&self) -> bool;
}

/// Trait for listening [`Rx`] interrupt events.
pub trait RxListen {
/// Start listening for an rx not empty interrupt event
///
/// Note, you will also have to enable the corresponding interrupt
/// in the NVIC to start receiving events.
fn listen(&mut self);

/// Stop listening for the rx not empty interrupt event
fn unlisten(&mut self);

/// Start listening for a line idle interrupt event
///
/// Note, you will also have to enable the corresponding interrupt
/// in the NVIC to start receiving events.
fn listen_idle(&mut self);
impl<UART: Instance> crate::Listen for Rx<UART> {
type Event = RxEvent;

/// Stop listening for the line idle interrupt event
fn unlisten_idle(&mut self);
#[inline(always)]
fn listen_event(
&mut self,
disable: Option<BitFlags<Self::Event>>,
enable: Option<BitFlags<Self::Event>>,
) {
self.usart.listen_rx(disable, enable)
}
}

/// Trait for listening [`Tx`] interrupt event.
pub trait TxListen {
/// Start listening for a tx empty interrupt event
///
/// Note, you will also have to enable the corresponding interrupt
/// in the NVIC to start receiving events.
fn listen(&mut self);
impl<UART: Instance> crate::Listen for Tx<UART> {
type Event = TxEvent;

/// Stop listening for the tx empty interrupt event
fn unlisten(&mut self);
#[inline(always)]
fn listen_event(
&mut self,
disable: Option<BitFlags<Self::Event>>,
enable: Option<BitFlags<Self::Event>>,
) {
self.usart.listen_tx(disable, enable)
}
}

/// Serial abstraction
Expand Down Expand Up @@ -578,34 +597,6 @@ impl<UART: Instance, WORD> TxISR for Tx<UART, WORD> {
}
}

impl<UART: Instance, WORD> RxListen for Rx<UART, WORD> {
fn listen(&mut self) {
self.usart.listen_rxne()
}

fn unlisten(&mut self) {
self.usart.unlisten_rxne()
}

fn listen_idle(&mut self) {
self.usart.listen_idle()
}

fn unlisten_idle(&mut self) {
self.usart.unlisten_idle()
}
}

impl<UART: Instance, WORD> TxListen for Tx<UART, WORD> {
fn listen(&mut self) {
self.usart.listen_txe()
}

fn unlisten(&mut self) {
self.usart.unlisten_txe()
}
}

impl<UART: Instance, WORD> crate::ClearFlags for Serial<UART, WORD> {
type Flag = CFlag;

Expand All @@ -628,20 +619,12 @@ impl<UART: Instance, WORD> crate::Listen for Serial<UART, WORD> {
type Event = Event;

#[inline(always)]
fn listen(&mut self, event: impl Into<BitFlags<Event>>) {
self.tx.usart.listen_event(None, Some(event.into()));
}

#[inline(always)]
fn listen_only(&mut self, event: impl Into<BitFlags<Self::Event>>) {
self.tx
.usart
.listen_event(Some(BitFlags::ALL), Some(event.into()));
}

#[inline(always)]
fn unlisten(&mut self, event: impl Into<BitFlags<Event>>) {
self.tx.usart.listen_event(Some(event.into()), None);
fn listen_event(
&mut self,
disable: Option<BitFlags<Self::Event>>,
enable: Option<BitFlags<Self::Event>>,
) {
self.tx.usart.listen_event(disable, enable)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/serial/dma.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::{marker::PhantomData, mem::transmute};

use super::{Instance, RegisterBlockImpl, Serial};
use super::{Instance, RBExt, Serial};
use crate::dma::{
config::DmaConfig,
traits::{Channel, DMASet, DmaFlagExt, PeriAddress, Stream, StreamISR},
Expand Down
4 changes: 2 additions & 2 deletions src/serial/hal_02.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod nb {
#[allow(unused)]
use super::super::RegisterBlockImpl;
use super::super::RBExt;
use super::super::{Error, Instance, Rx, Serial, Tx};
use embedded_hal_02::serial::{Read, Write};

Expand Down Expand Up @@ -84,7 +84,7 @@ mod blocking {
use core::ops::Deref;

#[allow(unused)]
use super::super::RegisterBlockImpl;
use super::super::RBExt;
use super::super::{Error, Instance, Serial, Tx};
use embedded_hal_02::blocking::serial::Write;

Expand Down
4 changes: 2 additions & 2 deletions src/serial/hal_1.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod nb {
#[allow(unused)]
use super::super::RegisterBlockImpl;
use super::super::RBExt;
use super::super::{Error, Instance, Rx, Serial, Tx};
use embedded_hal_nb::serial::{ErrorKind, Read, Write};

Expand Down Expand Up @@ -92,7 +92,7 @@ mod nb {

mod io {
#[allow(unused)]
use super::super::RegisterBlockImpl;
use super::super::RBExt;
use super::super::{Error, Instance, Rx, Serial, Tx};
use embedded_io::Write;

Expand Down
Loading