Skip to content

Commit 12b5bc1

Browse files
bors[bot]burrbull
andauthored
Merge #515
515: Deref for UTx, URx r=therealprof a=burrbull Removes boilerplate from #514 Co-authored-by: Andrey Zgarbul <zgarbul.andrey@gmail.com>
2 parents 1e12e92 + 3dcfeeb commit 12b5bc1

File tree

4 files changed

+79
-288
lines changed

4 files changed

+79
-288
lines changed

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2525

2626
### Added
2727

28-
- Serial Tx, Rx containing pins [#514]
28+
- Serial Tx, Rx containing pins [#514] [#515]
2929
- Implementation of From trait for Pin-to-PartiallyErasedPin [#507]
3030
- Implementation of From trait for Pin-to-ErasedPin [#507]
3131
- Implementation of From trait for PartiallyErasedPin-to-ErasedPin [#507]
@@ -39,7 +39,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3939
[#507]: https://github.com/stm32-rs/stm32f4xx-hal/pull/507
4040
[#508]: https://github.com/stm32-rs/stm32f4xx-hal/pull/508
4141
[#510]: https://github.com/stm32-rs/stm32f4xx-hal/pull/510
42-
[#510]: https://github.com/stm32-rs/stm32f4xx-hal/pull/514
42+
[#514]: https://github.com/stm32-rs/stm32f4xx-hal/pull/514
43+
[#515]: https://github.com/stm32-rs/stm32f4xx-hal/pull/515
4344

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

src/serial.rs

Lines changed: 72 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1919
use core::fmt;
2020
use core::marker::PhantomData;
21+
use core::ops::{Deref, DerefMut};
2122

2223
use crate::rcc;
2324
use nb::block;
@@ -309,107 +310,77 @@ impl<USART: Instance, WORD> Tx<USART, WORD> {
309310
}
310311

311312
impl<USART, PINS, WORD> AsRef<Tx<USART, WORD>> for Serial<USART, PINS, WORD> {
313+
#[inline(always)]
312314
fn as_ref(&self) -> &Tx<USART, WORD> {
313315
&self.tx
314316
}
315317
}
316318

317319
impl<USART, PINS, WORD> AsRef<Rx<USART, WORD>> for Serial<USART, PINS, WORD> {
320+
#[inline(always)]
318321
fn as_ref(&self) -> &Rx<USART, WORD> {
319322
&self.rx
320323
}
321324
}
322325

323326
impl<USART, PINS, WORD> AsMut<Tx<USART, WORD>> for Serial<USART, PINS, WORD> {
327+
#[inline(always)]
324328
fn as_mut(&mut self) -> &mut Tx<USART, WORD> {
325329
&mut self.tx
326330
}
327331
}
328332

329333
impl<USART, PINS, WORD> AsMut<Rx<USART, WORD>> for Serial<USART, PINS, WORD> {
334+
#[inline(always)]
330335
fn as_mut(&mut self) -> &mut Rx<USART, WORD> {
331336
&mut self.rx
332337
}
333338
}
334339

335340
/// Serial receiver containing RX pin
336341
pub struct URx<USART, RX, WORD = u8> {
337-
_usart: PhantomData<USART>,
342+
inner: Rx<USART, WORD>,
338343
pin: RX,
339-
_word: PhantomData<WORD>,
340344
}
341345

342346
/// Serial transmitter containing TX pin
343347
pub struct UTx<USART, TX, WORD = u8> {
348+
inner: Tx<USART, WORD>,
344349
usart: USART,
345350
pin: TX,
346-
_word: PhantomData<WORD>,
347351
}
348352

349353
impl<USART: Instance, RX, WORD> URx<USART, RX, WORD> {
350354
fn new(pin: RX) -> Self {
351355
Self {
352-
_usart: PhantomData,
356+
inner: Rx::new(),
353357
pin,
354-
_word: PhantomData,
355358
}
356359
}
357360

358361
pub fn erase(self) -> Rx<USART, WORD> {
359362
Rx::new()
360363
}
361364

362-
/// Start listening for an rx not empty interrupt event
363-
///
364-
/// Note, you will also have to enable the corresponding interrupt
365-
/// in the NVIC to start receiving events.
366-
pub fn listen(&mut self) {
367-
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.rxneie().set_bit()) }
368-
}
369-
370-
/// Stop listening for the rx not empty interrupt event
371-
pub fn unlisten(&mut self) {
372-
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.rxneie().clear_bit()) }
373-
}
374-
375-
/// Start listening for a line idle interrupt event
376-
///
377-
/// Note, you will also have to enable the corresponding interrupt
378-
/// in the NVIC to start receiving events.
379-
pub fn listen_idle(&mut self) {
380-
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.idleie().set_bit()) }
381-
}
382-
383-
/// Stop listening for the line idle interrupt event
384-
pub fn unlisten_idle(&mut self) {
385-
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit()) }
386-
}
387-
388-
/// Return true if the line idle status is set
389-
pub fn is_idle(&self) -> bool {
390-
unsafe { (*USART::ptr()).sr.read().idle().bit_is_set() }
391-
}
392-
393-
/// Return true if the rx register is not empty (and can be read)
394-
pub fn is_rx_not_empty(&self) -> bool {
395-
unsafe { (*USART::ptr()).sr.read().rxne().bit_is_set() }
396-
}
397-
398-
/// Clear idle line interrupt flag
399-
pub fn clear_idle_interrupt(&self) {
400-
unsafe {
401-
let _ = (*USART::ptr()).sr.read();
402-
let _ = (*USART::ptr()).dr.read();
365+
pub fn join<TX>(self, tx: UTx<USART, TX, WORD>) -> Serial<USART, (TX, RX), WORD>
366+
where
367+
(TX, RX): Pins<USART>,
368+
{
369+
Serial {
370+
usart: tx.usart,
371+
pins: (tx.pin, self.pin),
372+
tx: tx.inner,
373+
rx: self.inner,
403374
}
404375
}
405376
}
406377

407378
impl<USART: Instance, TX, WORD> UTx<USART, TX, WORD> {
408379
fn new(usart: USART, pin: TX) -> Self {
409380
Self {
381+
inner: Tx::new(),
410382
usart,
411383
pin,
412-
_word: PhantomData,
413384
}
414385
}
415386

@@ -424,28 +395,67 @@ impl<USART: Instance, TX, WORD> UTx<USART, TX, WORD> {
424395
Serial {
425396
usart: self.usart,
426397
pins: (self.pin, rx.pin),
427-
tx: Tx::new(),
428-
rx: Rx::new(),
398+
tx: self.inner,
399+
rx: rx.inner,
429400
}
430401
}
402+
}
431403

432-
/// Start listening for a tx empty interrupt event
433-
///
434-
/// Note, you will also have to enable the corresponding interrupt
435-
/// in the NVIC to start receiving events.
436-
// TODO: replace with "self.usart"
437-
pub fn listen(&mut self) {
438-
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.txeie().set_bit()) }
404+
impl<USART, TX, WORD> AsRef<Tx<USART, WORD>> for UTx<USART, TX, WORD> {
405+
#[inline(always)]
406+
fn as_ref(&self) -> &Tx<USART, WORD> {
407+
&self.inner
439408
}
409+
}
440410

441-
/// Stop listening for the tx empty interrupt event
442-
pub fn unlisten(&mut self) {
443-
unsafe { (*USART::ptr()).cr1.modify(|_, w| w.txeie().clear_bit()) }
411+
impl<USART, TX, WORD> Deref for UTx<USART, TX, WORD> {
412+
type Target = Tx<USART, WORD>;
413+
#[inline(always)]
414+
fn deref(&self) -> &Self::Target {
415+
&self.inner
444416
}
417+
}
445418

446-
/// Return true if the tx register is empty (and can accept data)
447-
pub fn is_tx_empty(&self) -> bool {
448-
unsafe { (*USART::ptr()).sr.read().txe().bit_is_set() }
419+
impl<USART, RX, WORD> AsRef<Rx<USART, WORD>> for URx<USART, RX, WORD> {
420+
#[inline(always)]
421+
fn as_ref(&self) -> &Rx<USART, WORD> {
422+
&self.inner
423+
}
424+
}
425+
426+
impl<USART, RX, WORD> Deref for URx<USART, RX, WORD> {
427+
type Target = Rx<USART, WORD>;
428+
#[inline(always)]
429+
fn deref(&self) -> &Self::Target {
430+
&self.inner
431+
}
432+
}
433+
434+
impl<USART, TX, WORD> AsMut<Tx<USART, WORD>> for UTx<USART, TX, WORD> {
435+
#[inline(always)]
436+
fn as_mut(&mut self) -> &mut Tx<USART, WORD> {
437+
&mut self.inner
438+
}
439+
}
440+
441+
impl<USART, TX, WORD> DerefMut for UTx<USART, TX, WORD> {
442+
#[inline(always)]
443+
fn deref_mut(&mut self) -> &mut Self::Target {
444+
&mut self.inner
445+
}
446+
}
447+
448+
impl<USART, RX, WORD> AsMut<Rx<USART, WORD>> for URx<USART, RX, WORD> {
449+
#[inline(always)]
450+
fn as_mut(&mut self) -> &mut Rx<USART, WORD> {
451+
&mut self.inner
452+
}
453+
}
454+
455+
impl<USART, RX, WORD> DerefMut for URx<USART, RX, WORD> {
456+
#[inline(always)]
457+
fn deref_mut(&mut self) -> &mut Self::Target {
458+
&mut self.inner
449459
}
450460
}
451461

@@ -1035,109 +1045,3 @@ impl<USART: Instance> Tx<USART, u16> {
10351045
nb::block!(self.flush())
10361046
}
10371047
}
1038-
1039-
impl<USART: Instance, TX> fmt::Write for UTx<USART, TX> {
1040-
fn write_str(&mut self, s: &str) -> fmt::Result {
1041-
s.bytes()
1042-
.try_for_each(|c| block!(self.write(c)))
1043-
.map_err(|_| fmt::Error)
1044-
}
1045-
}
1046-
1047-
impl<USART: Instance, RX> URx<USART, RX, u8> {
1048-
fn read(&mut self) -> nb::Result<u8, Error> {
1049-
// Delegate to the Read<u16> implementation, then truncate to 8 bits
1050-
Rx::<USART, u16>::new().read().map(|word16| word16 as u8)
1051-
}
1052-
}
1053-
1054-
impl<USART: Instance, RX> URx<USART, RX, u16> {
1055-
fn read(&mut self) -> nb::Result<u16, Error> {
1056-
// NOTE(unsafe) atomic read with no side effects
1057-
let sr = unsafe { (*USART::ptr()).sr.read() };
1058-
1059-
// Any error requires the dr to be read to clear
1060-
if sr.pe().bit_is_set()
1061-
|| sr.fe().bit_is_set()
1062-
|| sr.nf().bit_is_set()
1063-
|| sr.ore().bit_is_set()
1064-
{
1065-
unsafe { (*USART::ptr()).dr.read() };
1066-
}
1067-
1068-
Err(if sr.pe().bit_is_set() {
1069-
Error::Parity.into()
1070-
} else if sr.fe().bit_is_set() {
1071-
Error::FrameFormat.into()
1072-
} else if sr.nf().bit_is_set() {
1073-
Error::Noise.into()
1074-
} else if sr.ore().bit_is_set() {
1075-
Error::Overrun.into()
1076-
} else if sr.rxne().bit_is_set() {
1077-
// NOTE(unsafe) atomic read from stateless register
1078-
return Ok(unsafe { &*USART::ptr() }.dr.read().dr().bits());
1079-
} else {
1080-
nb::Error::WouldBlock
1081-
})
1082-
}
1083-
}
1084-
1085-
impl<USART: Instance, TX> UTx<USART, TX, u8> {
1086-
fn write(&mut self, word: u8) -> nb::Result<(), Error> {
1087-
// Delegate to u16 version
1088-
Tx::<USART, u16>::new().write(u16::from(word))
1089-
}
1090-
1091-
fn flush(&mut self) -> nb::Result<(), Error> {
1092-
// Delegate to u16 version
1093-
Tx::<USART, u16>::new().flush()
1094-
}
1095-
1096-
fn bwrite_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
1097-
for &b in bytes {
1098-
nb::block!(self.write(b))?;
1099-
}
1100-
Ok(())
1101-
}
1102-
1103-
fn bflush(&mut self) -> Result<(), Error> {
1104-
nb::block!(self.flush())
1105-
}
1106-
}
1107-
1108-
impl<USART: Instance, TX> UTx<USART, TX, u16> {
1109-
fn write(&mut self, word: u16) -> nb::Result<(), Error> {
1110-
// NOTE(unsafe) atomic read with no side effects
1111-
let sr = unsafe { (*USART::ptr()).sr.read() };
1112-
1113-
if sr.txe().bit_is_set() {
1114-
// NOTE(unsafe) atomic write to stateless register
1115-
unsafe { &*USART::ptr() }.dr.write(|w| w.dr().bits(word));
1116-
Ok(())
1117-
} else {
1118-
Err(nb::Error::WouldBlock)
1119-
}
1120-
}
1121-
1122-
fn flush(&mut self) -> nb::Result<(), Error> {
1123-
// NOTE(unsafe) atomic read with no side effects
1124-
let sr = unsafe { (*USART::ptr()).sr.read() };
1125-
1126-
if sr.tc().bit_is_set() {
1127-
Ok(())
1128-
} else {
1129-
Err(nb::Error::WouldBlock)
1130-
}
1131-
}
1132-
1133-
fn bwrite_all(&mut self, buffer: &[u16]) -> Result<(), Error> {
1134-
for &b in buffer {
1135-
nb::block!(self.write(b))?;
1136-
}
1137-
Ok(())
1138-
}
1139-
1140-
fn bflush(&mut self) -> Result<(), Error> {
1141-
nb::block!(self.flush())
1142-
}
1143-
}

0 commit comments

Comments
 (0)