Skip to content

Commit c608b8e

Browse files
committed
Support reunite in serial::{Rx,Tx}
This becomes relevant as more functions like reconfigure are added to the Serial structs. Fixes stm32-rs#386.
1 parent 1c285b1 commit c608b8e

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

examples/serial.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,13 @@ fn main() -> ! {
8888
assert_eq!(received, sent);
8989
asm::bkpt();
9090

91+
// And later reunite it again
92+
let mut serial = tx.reunite(rx);
93+
let sent = b'Z';
94+
block!(serial.write(sent)).ok();
95+
let received = block!(serial.read()).unwrap();
96+
assert_eq!(received, sent);
97+
asm::bkpt();
98+
9199
loop {}
92100
}

src/serial.rs

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ pub struct Serial<USART, PINS> {
190190
}
191191

192192
pub struct ErasedSerial<USART> {
193-
usart: USART,
194193
tx: Tx<USART>,
195194
rx: Rx<USART>,
196195
}
@@ -209,7 +208,7 @@ pub struct Rx<USART> {
209208

210209
/// Serial transmitter
211210
pub struct Tx<USART> {
212-
_usart: PhantomData<USART>,
211+
usart: USART,
213212
}
214213

215214
impl<USART> Rx<USART> {
@@ -218,13 +217,21 @@ impl<USART> Rx<USART> {
218217
_usart: PhantomData,
219218
}
220219
}
220+
221+
/// Reunite the two halves of a split serial
222+
pub fn reunite(self, tx: Tx<USART>) -> ErasedSerial<USART> {
223+
ErasedSerial { rx: self, tx }
224+
}
221225
}
222226

223227
impl<USART> Tx<USART> {
224-
fn new() -> Self {
225-
Self {
226-
_usart: PhantomData,
227-
}
228+
fn new(usart: USART) -> Self {
229+
Self { usart }
230+
}
231+
232+
/// Reunite the two halves of a split serial
233+
pub fn reunite(self, rx: Rx<USART>) -> ErasedSerial<USART> {
234+
ErasedSerial { tx: self, rx }
228235
}
229236
}
230237

@@ -244,7 +251,8 @@ where
244251
// UE: enable USART
245252
// RE: enable receiver
246253
// TE: enable transceiver
247-
self.usart
254+
self.tx
255+
.usart
248256
.cr1
249257
.modify(|_r, w| w.ue().set_bit().re().set_bit().te().set_bit());
250258

@@ -255,7 +263,7 @@ where
255263
// Configure baud rate
256264
let brr = USART::get_frequency(&clocks).0 / config.baudrate.0;
257265
assert!(brr >= 16, "impossible baud rate");
258-
self.usart.brr.write(|w| unsafe { w.bits(brr) });
266+
self.tx.usart.brr.write(|w| unsafe { w.bits(brr) });
259267

260268
// Configure parity and word length
261269
// Unlike most uart devices, the "word length" of this usart device refers to
@@ -267,7 +275,7 @@ where
267275
Parity::ParityEven => (true, true, false),
268276
Parity::ParityOdd => (true, true, true),
269277
};
270-
self.usart.cr1.modify(|_r, w| {
278+
self.tx.usart.cr1.modify(|_r, w| {
271279
w.m()
272280
.bit(word_length)
273281
.ps()
@@ -283,7 +291,7 @@ where
283291
StopBits::STOP2 => 0b10,
284292
StopBits::STOP1P5 => 0b11,
285293
};
286-
self.usart.cr2.modify(|_r, w| w.stop().bits(stop_bits));
294+
self.tx.usart.cr2.modify(|_r, w| w.stop().bits(stop_bits));
287295
}
288296

289297
/// Reconfigure the USART instance.
@@ -295,7 +303,7 @@ where
295303
config: impl Into<Config>,
296304
clocks: Clocks,
297305
) -> nb::Result<(), Infallible> {
298-
let sr = self.usart.sr.read();
306+
let sr = self.tx.usart.sr.read();
299307
// if we're currently busy transmitting, we have to wait until that is
300308
// over -- regarding reception, we assume that the caller -- with
301309
// exclusive access to the Serial instance due to &mut self -- knows
@@ -312,9 +320,9 @@ where
312320
/// register empty (TXE)_ interrupt
313321
pub fn listen(&mut self, event: Event) {
314322
match event {
315-
Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
316-
Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
317-
Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()),
323+
Event::Rxne => self.tx.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
324+
Event::Txe => self.tx.usart.cr1.modify(|_, w| w.txeie().set_bit()),
325+
Event::Idle => self.tx.usart.cr1.modify(|_, w| w.idleie().set_bit()),
318326
}
319327
}
320328

@@ -323,25 +331,25 @@ where
323331
/// register empty (TXE)_ interrupt
324332
pub fn unlisten(&mut self, event: Event) {
325333
match event {
326-
Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
327-
Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
328-
Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
334+
Event::Rxne => self.tx.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
335+
Event::Txe => self.tx.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
336+
Event::Idle => self.tx.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
329337
}
330338
}
331339

332340
/// Returns true if the line idle status is set
333341
pub fn is_idle(&self) -> bool {
334-
self.usart.sr.read().idle().bit_is_set()
342+
self.tx.usart.sr.read().idle().bit_is_set()
335343
}
336344

337345
/// Returns true if the tx register is empty (and can accept data)
338346
pub fn is_tx_empty(&self) -> bool {
339-
self.usart.sr.read().txe().bit_is_set()
347+
self.tx.usart.sr.read().txe().bit_is_set()
340348
}
341349

342350
/// Returns true if the rx register is not empty (and can be read)
343351
pub fn is_rx_not_empty(&self) -> bool {
344-
self.usart.sr.read().rxne().bit_is_set()
352+
self.tx.usart.sr.read().rxne().bit_is_set()
345353
}
346354

347355
/// Clear idle line interrupt flag
@@ -365,7 +373,7 @@ where
365373
{
366374
/// Returns ownership of the borrowed register handles
367375
pub fn release(self) -> (USART, PINS) {
368-
(self.inner.usart, self.pins)
376+
(self.inner.tx.usart, self.pins)
369377
}
370378

371379
/// Erase the pins used for the Serial from the type
@@ -385,7 +393,11 @@ where
385393
/// If a transmission is currently in progress, this returns
386394
/// [`nb::Error::WouldBlock`].
387395
#[inline(always)]
388-
pub fn reconfigure(&mut self, config: impl Into<Config>, clocks: Clocks) -> nb::Result<(), ()> {
396+
pub fn reconfigure(
397+
&mut self,
398+
config: impl Into<Config>,
399+
clocks: Clocks,
400+
) -> nb::Result<(), Infallible> {
389401
self.inner.reconfigure(config, clocks)
390402
}
391403

@@ -476,7 +488,7 @@ macro_rules! hal {
476488
PINS: Pins<$USARTX>,
477489
{
478490
#[allow(unused_unsafe)]
479-
Serial { pins, inner: ErasedSerial{ usart, tx: Tx::new(), rx: Rx::new() }.init(config.into(), clocks, || {
491+
Serial { pins, inner: ErasedSerial{ tx: Tx::new(usart), rx: Rx::new() }.init(config.into(), clocks, || {
480492
mapr.modify_mapr(|_, w| unsafe {
481493
#[allow(clippy::redundant_closure_call)]
482494
w.$usartX_remap().$bit(($closure)(PINS::REMAP))

0 commit comments

Comments
 (0)