Skip to content

Commit 45678eb

Browse files
committed
serial: Lift generic constraint on pins for most functions
1 parent 1105421 commit 45678eb

File tree

3 files changed

+74
-63
lines changed

3 files changed

+74
-63
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
4545
detection of the `Serial`. If overrun is disabled (enabled by default), than
4646
newly arrived bytes are overwriting the current data in the read receive
4747
register without throwing any event. ([#253]).
48+
- Lift generic constraint of most `Serial` method on `TxPin` and `RxPin`.
49+
This should make it easier to generically use the `Serial` peripheral. ([#253])
4850

4951
[`enumset`]: https://crates.io/crates/enumset
5052

src/serial.rs

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,16 @@ mod split {
444444
Tx { usart, pin }
445445
}
446446

447+
/// Destruct [`Tx`] to regain access to underlying USART and pin.
448+
pub(crate) fn free(self) -> (Usart, Pin) {
449+
(self.usart, self.pin)
450+
}
451+
}
452+
453+
impl<Usart, Pin> Tx<Usart, Pin>
454+
where
455+
Usart: Instance,
456+
{
447457
/// Get a reference to internal usart peripheral
448458
///
449459
/// # Safety
@@ -472,11 +482,6 @@ mod split {
472482
pub(crate) unsafe fn usart_mut(&mut self) -> &mut Usart {
473483
&mut self.usart
474484
}
475-
476-
/// Destruct [`Tx`] to regain access to underlying USART and pin.
477-
pub(crate) fn free(self) -> (Usart, Pin) {
478-
(self.usart, self.pin)
479-
}
480485
}
481486

482487
impl<Usart, Pin> Rx<Usart, Pin>
@@ -488,6 +493,20 @@ mod split {
488493
Rx { usart, pin }
489494
}
490495

496+
/// Destruct [`Rx`] to regain access to the underlying pin.
497+
///
498+
/// The USART is omitted, as it is returnend from Tx already to avoid
499+
/// beeing able to crate a duplicate reference to the same underlying
500+
/// peripheral.
501+
pub(crate) fn free(self) -> Pin {
502+
self.pin
503+
}
504+
}
505+
506+
impl<Usart, Pin> Rx<Usart, Pin>
507+
where
508+
Usart: Instance,
509+
{
491510
/// Get a reference to internal usart peripheral
492511
///
493512
/// # Safety
@@ -515,15 +534,6 @@ mod split {
515534
pub(crate) unsafe fn usart_mut(&mut self) -> &mut Usart {
516535
&mut self.usart
517536
}
518-
519-
/// Destruct [`Rx`] to regain access to the underlying pin.
520-
///
521-
/// The USART is omitted, as it is returnend from Tx already to avoid
522-
/// beeing able to crate a duplicate reference to the same underlying
523-
/// peripheral.
524-
pub(crate) fn free(self) -> Pin {
525-
self.pin
526-
}
527537
}
528538
}
529539

@@ -586,6 +596,48 @@ where
586596
Self { usart, pins }
587597
}
588598

599+
/// Releases the USART peripheral and associated pins
600+
pub fn free(self) -> (Usart, (Tx, Rx)) {
601+
self.usart
602+
.cr1
603+
.modify(|_, w| w.ue().disabled().re().disabled().te().disabled());
604+
(self.usart, self.pins)
605+
}
606+
607+
/// Joins previously [`Serial::split()`] serial.
608+
///
609+
/// This is often needed to access methods only implemented for [`Serial`]
610+
/// but not for [`Tx`] nor [`Rx`].
611+
///
612+
/// # Example
613+
///
614+
/// ```
615+
/// let dp = pac::Peripherals::take().unwrap();
616+
///
617+
/// (tx, rx) = Serial::new(dp.USART1, ...).split();
618+
///
619+
/// // Do something with tx and rx
620+
///
621+
/// serial = Serial::join(tx, rx);
622+
/// ```
623+
pub fn join(tx: split::Tx<Usart, Tx>, rx: split::Rx<Usart, Rx>) -> Self
624+
where
625+
Tx: TxPin<Usart>,
626+
Rx: RxPin<Usart>,
627+
{
628+
let (usart, tx_pin) = tx.free();
629+
let rx_pin = rx.free();
630+
Self {
631+
usart,
632+
pins: (tx_pin, rx_pin),
633+
}
634+
}
635+
}
636+
637+
impl<Usart, Pins> Serial<Usart, Pins>
638+
where
639+
Usart: Instance,
640+
{
589641
/// Serial read out of the read register
590642
///
591643
/// No error handling and no additional side-effects, besides the implied
@@ -806,43 +858,6 @@ where
806858
pub fn match_character(&self) -> u8 {
807859
self.usart.cr2.read().add().bits()
808860
}
809-
810-
/// Releases the USART peripheral and associated pins
811-
pub fn free(self) -> (Usart, (Tx, Rx)) {
812-
self.usart
813-
.cr1
814-
.modify(|_, w| w.ue().disabled().re().disabled().te().disabled());
815-
(self.usart, self.pins)
816-
}
817-
818-
/// Joins previously [`Serial::split()`] serial.
819-
///
820-
/// This is often needed to access methods only implemented for [`Serial`]
821-
/// but not for [`Tx`] nor [`Rx`].
822-
///
823-
/// # Example
824-
///
825-
/// ```
826-
/// let dp = pac::Peripherals::take().unwrap();
827-
///
828-
/// (tx, rx) = Serial::new(dp.USART1, ...).split();
829-
///
830-
/// // Do something with tx and rx
831-
///
832-
/// serial = Serial::join(tx, rx);
833-
/// ```
834-
pub fn join(tx: split::Tx<Usart, Tx>, rx: split::Rx<Usart, Rx>) -> Self
835-
where
836-
Tx: TxPin<Usart>,
837-
Rx: RxPin<Usart>,
838-
{
839-
let (usart, tx_pin) = tx.free();
840-
let rx_pin = rx.free();
841-
Self {
842-
usart,
843-
pins: (tx_pin, rx_pin),
844-
}
845-
}
846861
}
847862

848863
impl<Usart, Tx, Rx> Serial<Usart, (Tx, Rx)>
@@ -1057,7 +1072,6 @@ where
10571072
impl<Usart, Pin> Rx<Usart, Pin>
10581073
where
10591074
Usart: Instance + Dma,
1060-
Pin: RxPin<Usart>,
10611075
{
10621076
/// Fill the buffer with received data using DMA.
10631077
pub fn read_exact<B, C>(self, buffer: B, mut channel: C) -> dma::Transfer<B, C, Self>
@@ -1112,7 +1126,6 @@ where
11121126
impl<Usart, Pin> dma::Target for Rx<Usart, Pin>
11131127
where
11141128
Usart: Instance + Dma,
1115-
Pin: RxPin<Usart>,
11161129
{
11171130
fn enable_dma(&mut self) {
11181131
// NOTE(unsafe) critical section prevents races
@@ -1149,11 +1162,9 @@ where
11491162
}
11501163
}
11511164

1152-
impl<Usart, Tx, Rx> Serial<Usart, (Tx, Rx)>
1165+
impl<Usart, Pins> Serial<Usart, Pins>
11531166
where
11541167
Usart: Instance + Dma,
1155-
Rx: RxPin<Usart>,
1156-
Tx: TxPin<Usart>,
11571168
{
11581169
/// Fill the buffer with received data using DMA.
11591170
pub fn read_exact<B, C>(self, buffer: B, mut channel: C) -> dma::Transfer<B, C, Self>
@@ -1188,7 +1199,7 @@ where
11881199
}
11891200
}
11901201

1191-
impl<Usart, Tx, Rx> dma::Target for Serial<Usart, (Tx, Rx)>
1202+
impl<Usart, Pins> dma::Target for Serial<Usart, Pins>
11921203
where
11931204
Usart: Instance + Dma,
11941205
{

testsuite/tests/uart.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hal::pac;
1212
use hal::prelude::*;
1313
use hal::serial::{
1414
config::{Config, Parity, StopBits},
15-
Error, Event, Instance, Serial, TxPin, RxPin,
15+
Error, Event, Instance, Serial,
1616
};
1717
use hal::time::rate::Baud;
1818
use hal::{
@@ -58,14 +58,12 @@ fn test_test_msg_loopback(state: &mut State, config: impl Into<Config>) {
5858
state.serial1 = Some(serial);
5959
}
6060

61-
fn trigger_event<Usart, Tx, Rx>(
61+
fn trigger_event<Usart, Pins>(
6262
event: Event,
63-
serial: &mut Serial<Usart, (Tx, Rx)>,
64-
mut trigger: impl FnMut(&mut Serial<Usart, (Tx, Rx)>),
63+
serial: &mut Serial<Usart, Pins>,
64+
mut trigger: impl FnMut(&mut Serial<Usart, Pins>),
6565
) where
6666
Usart: Instance,
67-
Tx: TxPin<Usart>,
68-
Rx: RxPin<Usart>,
6967
{
7068
// Create an enumset of events with only one
7169
// event. Applying it disabled all other interrupts.

0 commit comments

Comments
 (0)