Skip to content

Commit

Permalink
Merge pull request #768 from stm32-rs/uart-steal
Browse files Browse the repository at this point in the history
UART::steal & Deref
  • Loading branch information
therealprof committed Jul 16, 2024
2 parents dec5ea1 + 40b5a14 commit 2ad56a7
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 149 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Use `stm32f4-staging` until `stm32f4` is released [#706]
- RTIC2 monotonics fix: CC1 instead of CC3
- Allow different lengths of buffers in hal_1 SpiBus impl [#566]
- `steal` UART peripheral on `Rx::new`

[#566]: https://github.com/stm32-rs/stm32f4xx-hal/pull/566
[#706]: https://github.com/stm32-rs/stm32f4xx-hal/pull/706
Expand Down
14 changes: 8 additions & 6 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ pub struct Serial<USART: CommonPins, WORD = u8> {

/// Serial receiver containing RX pin
pub struct Rx<USART: CommonPins, WORD = u8> {
_word: PhantomData<(USART, WORD)>,
_word: PhantomData<WORD>,
usart: USART,
pin: USART::Rx<PushPull>,
}

Expand Down Expand Up @@ -276,8 +277,8 @@ macro_rules! halUsart {
});
}

fn peri_address() -> u32 {
unsafe { (*(<$USART>::ptr() as *const Self::RegisterBlock)).peri_address() }
unsafe fn steal() -> Self {
Self::steal()
}
}
};
Expand All @@ -293,13 +294,13 @@ halUsart! { pac::USART3, Serial3, Rx3, Tx3 }

impl<UART: CommonPins> Rx<UART, u8> {
pub(crate) fn with_u16_data(self) -> Rx<UART, u16> {
Rx::new(self.pin)
Rx::new(self.usart, self.pin)
}
}

impl<UART: CommonPins> Rx<UART, u16> {
pub(crate) fn with_u8_data(self) -> Rx<UART, u8> {
Rx::new(self.pin)
Rx::new(self.usart, self.pin)
}
}

Expand All @@ -316,9 +317,10 @@ impl<UART: CommonPins> Tx<UART, u16> {
}

impl<UART: CommonPins, WORD> Rx<UART, WORD> {
pub(crate) fn new(pin: UART::Rx<PushPull>) -> Self {
pub(crate) fn new(usart: UART, pin: UART::Rx<PushPull>) -> Self {
Self {
_word: PhantomData,
usart,
pin,
}
}
Expand Down
49 changes: 9 additions & 40 deletions src/serial/dma.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::{marker::PhantomData, mem::transmute, ops::Deref};
use core::{marker::PhantomData, mem::transmute};

use super::{Instance, RegisterBlockImpl, Serial};
use crate::dma::{
Expand Down Expand Up @@ -67,12 +67,7 @@ pub trait SerialHandleIT {
fn handle_error_interrupt(&mut self);
}

impl<Serial_> Serial<Serial_>
where
Serial_: Instance,
Serial_: Deref<Target = <Serial_ as Instance>::RegisterBlock>,
<Serial_ as Instance>::RegisterBlock: RegisterBlockImpl,
{
impl<Serial_: Instance> Serial<Serial_> {
/// Converts blocking [Serial] to non-blocking [SerialDma] that use `tx_stream` and `rx_stream` to send/receive data
pub fn use_dma<TX_STREAM, const TX_CH: u8, RX_STREAM, const RX_CH: u8>(
self,
Expand Down Expand Up @@ -152,10 +147,7 @@ where
///
/// The struct can be also used to send/receive bytes in blocking mode with methods:
/// [`write`](Self::write()), [`read`](Self::read()), [`write_read`](Self::write_read()).
pub struct SerialDma<Serial_, TX_TRANSFER, RX_TRANSFER>
where
Serial_: Instance,
{
pub struct SerialDma<Serial_: Instance, TX_TRANSFER, RX_TRANSFER> {
hal_serial: Serial<Serial_>,
callback: Option<SerialCompleteCallback>,
tx: TX_TRANSFER,
Expand Down Expand Up @@ -338,11 +330,8 @@ where
}

/// Common implementation
impl<Serial_, TX_TRANSFER, RX_TRANSFER> SerialDma<Serial_, TX_TRANSFER, RX_TRANSFER>
impl<Serial_: Instance, TX_TRANSFER, RX_TRANSFER> SerialDma<Serial_, TX_TRANSFER, RX_TRANSFER>
where
Serial_: Instance,
Serial_: Deref<Target = <Serial_ as Instance>::RegisterBlock>,
<Serial_ as Instance>::RegisterBlock: RegisterBlockImpl,
TX_TRANSFER: DMATransfer<&'static [u8]>,
RX_TRANSFER: DMATransfer<&'static mut [u8]>,
{
Expand Down Expand Up @@ -386,13 +375,9 @@ where
}
}

impl<Serial_, TX_STREAM, const TX_CH: u8> SerialHandleIT
impl<Serial_: Instance, TX_STREAM, const TX_CH: u8> SerialHandleIT
for SerialDma<Serial_, TxDMA<Serial_, TX_STREAM, TX_CH>, NoDMA>
where
Serial_: Instance,
Serial_: Deref<Target = <Serial_ as Instance>::RegisterBlock>,
<Serial_ as Instance>::RegisterBlock: RegisterBlockImpl,

TX_STREAM: Stream,
ChannelX<TX_CH>: Channel,
Tx<Serial_>: DMASet<TX_STREAM, TX_CH, MemoryToPeripheral>,
Expand Down Expand Up @@ -428,13 +413,9 @@ where
}
}

impl<Serial_, RX_STREAM, const RX_CH: u8> SerialHandleIT
impl<Serial_: Instance, RX_STREAM, const RX_CH: u8> SerialHandleIT
for SerialDma<Serial_, NoDMA, RxDMA<Serial_, RX_STREAM, RX_CH>>
where
Serial_: Instance,
Serial_: Deref<Target = <Serial_ as Instance>::RegisterBlock>,
<Serial_ as Instance>::RegisterBlock: RegisterBlockImpl,

RX_STREAM: Stream,
ChannelX<RX_CH>: Channel,
Rx<Serial_>: DMASet<RX_STREAM, RX_CH, PeripheralToMemory>,
Expand Down Expand Up @@ -471,13 +452,9 @@ where
}

/// Only for both TX and RX DMA
impl<Serial_, TX_STREAM, const TX_CH: u8, RX_STREAM, const RX_CH: u8> SerialHandleIT
impl<Serial_: Instance, TX_STREAM, const TX_CH: u8, RX_STREAM, const RX_CH: u8> SerialHandleIT
for SerialDma<Serial_, TxDMA<Serial_, TX_STREAM, TX_CH>, RxDMA<Serial_, RX_STREAM, RX_CH>>
where
Serial_: Instance,
Serial_: Deref<Target = <Serial_ as Instance>::RegisterBlock>,
<Serial_ as Instance>::RegisterBlock: RegisterBlockImpl,

TX_STREAM: Stream,
ChannelX<TX_CH>: Channel,
Tx<Serial_>: DMASet<TX_STREAM, TX_CH, MemoryToPeripheral>,
Expand Down Expand Up @@ -550,13 +527,9 @@ where
}

// Write DMA implementations for TX only and TX/RX Serial DMA
impl<Serial_, TX_STREAM, const TX_CH: u8, RX_TRANSFER> SerialWriteDMA
impl<Serial_: Instance, TX_STREAM, const TX_CH: u8, RX_TRANSFER> SerialWriteDMA
for SerialDma<Serial_, TxDMA<Serial_, TX_STREAM, TX_CH>, RX_TRANSFER>
where
Serial_: Instance,
Serial_: Deref<Target = <Serial_ as Instance>::RegisterBlock>,
<Serial_ as Instance>::RegisterBlock: RegisterBlockImpl,

TX_STREAM: Stream,
ChannelX<TX_CH>: Channel,
Tx<Serial_>: DMASet<TX_STREAM, TX_CH, MemoryToPeripheral>,
Expand All @@ -581,13 +554,9 @@ where
}

// Read DMA implementations for RX only and TX/RX Serial DMA
impl<Serial_, TX_TRANSFER, RX_STREAM, const RX_CH: u8> SerialReadDMA
impl<Serial_: Instance, TX_TRANSFER, RX_STREAM, const RX_CH: u8> SerialReadDMA
for SerialDma<Serial_, TX_TRANSFER, RxDMA<Serial_, RX_STREAM, RX_CH>>
where
Serial_: Instance,
Serial_: Deref<Target = <Serial_ as Instance>::RegisterBlock>,
<Serial_ as Instance>::RegisterBlock: RegisterBlockImpl,

RX_STREAM: Stream,
ChannelX<RX_CH>: Channel,
Rx<Serial_>: DMASet<RX_STREAM, RX_CH, PeripheralToMemory>,
Expand Down
20 changes: 5 additions & 15 deletions src/serial/hal_02.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod nb {
use core::ops::Deref;

use super::super::{Error, Instance, RegisterBlockImpl, Rx, Serial, Tx};
use embedded_hal_02::serial::{Read, Write};
Expand All @@ -19,7 +18,7 @@ mod nb {
type Error = Error;

fn read(&mut self) -> nb::Result<u8, Self::Error> {
unsafe { (*USART::ptr()).read_u8() }
self.usart.read_u8()
}
}

Expand All @@ -32,7 +31,7 @@ mod nb {
type Error = Error;

fn read(&mut self) -> nb::Result<u16, Self::Error> {
unsafe { (*USART::ptr()).read_u16() }
self.usart.read_u16()
}
}

Expand All @@ -51,10 +50,7 @@ mod nb {
}
}

impl<USART: Instance> Write<u8> for Tx<USART, u8>
where
USART: Deref<Target = <USART as Instance>::RegisterBlock>,
{
impl<USART: Instance> Write<u8> for Tx<USART, u8> {
type Error = Error;

fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
Expand All @@ -70,10 +66,7 @@ mod nb {
/// If the UART/USART was configured with `WordLength::DataBits9`, the 9 least significant bits will
/// be transmitted and the other 7 bits will be ignored. Otherwise, the 8 least significant bits
/// will be transmitted and the other 8 bits will be ignored.
impl<USART: Instance> Write<u16> for Tx<USART, u16>
where
USART: Deref<Target = <USART as Instance>::RegisterBlock>,
{
impl<USART: Instance> Write<u16> for Tx<USART, u16> {
type Error = Error;

fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
Expand All @@ -92,10 +85,7 @@ mod blocking {
use super::super::{Error, Instance, RegisterBlockImpl, Serial, Tx};
use embedded_hal_02::blocking::serial::Write;

impl<USART: Instance> Write<u8> for Tx<USART, u8>
where
USART: Deref<Target = <USART as Instance>::RegisterBlock>,
{
impl<USART: Instance> Write<u8> for Tx<USART, u8> {
type Error = Error;

fn bwrite_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
Expand Down
16 changes: 4 additions & 12 deletions src/serial/hal_1.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
mod nb {
use core::ops::Deref;

use super::super::{Error, Instance, RegisterBlockImpl, Rx, Serial, Tx};
use embedded_hal_nb::serial::{ErrorKind, Read, Write};

Expand Down Expand Up @@ -37,7 +35,7 @@ mod nb {

impl<USART: Instance> Read<u8> for Rx<USART, u8> {
fn read(&mut self) -> nb::Result<u8, Self::Error> {
unsafe { (*USART::ptr()).read_u8() }
self.usart.read_u8()
}
}

Expand All @@ -48,7 +46,7 @@ mod nb {
/// 8 received data bits and all other bits set to zero.
impl<USART: Instance> Read<u16> for Rx<USART, u16> {
fn read(&mut self) -> nb::Result<u16, Self::Error> {
unsafe { (*USART::ptr()).read_u16() }
self.usart.read_u16()
}
}

Expand All @@ -65,10 +63,7 @@ mod nb {
}
}

impl<USART: Instance> Write<u8> for Tx<USART, u8>
where
USART: Deref<Target = <USART as Instance>::RegisterBlock>,
{
impl<USART: Instance> Write<u8> for Tx<USART, u8> {
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.usart.write_u8(word)
}
Expand All @@ -82,10 +77,7 @@ mod nb {
/// If the UART/USART was configured with `WordLength::DataBits9`, the 9 least significant bits will
/// be transmitted and the other 7 bits will be ignored. Otherwise, the 8 least significant bits
/// will be transmitted and the other 8 bits will be ignored.
impl<USART: Instance> Write<u16> for Tx<USART, u16>
where
USART: Deref<Target = <USART as Instance>::RegisterBlock>,
{
impl<USART: Instance> Write<u16> for Tx<USART, u16> {
fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
self.usart.write_u16(word)
}
Expand Down
Loading

0 comments on commit 2ad56a7

Please sign in to comment.