Skip to content

Commit 3bc7c7f

Browse files
committed
Deref for UTx
1 parent 1e12e92 commit 3bc7c7f

File tree

4 files changed

+67
-288
lines changed

4 files changed

+67
-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: 60 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;
@@ -334,82 +335,48 @@ impl<USART, PINS, WORD> AsMut<Rx<USART, WORD>> for Serial<USART, PINS, WORD> {
334335

335336
/// Serial receiver containing RX pin
336337
pub struct URx<USART, RX, WORD = u8> {
337-
_usart: PhantomData<USART>,
338+
inner: Rx<USART, WORD>,
338339
pin: RX,
339-
_word: PhantomData<WORD>,
340340
}
341341

342342
/// Serial transmitter containing TX pin
343343
pub struct UTx<USART, TX, WORD = u8> {
344+
inner: Tx<USART, WORD>,
344345
usart: USART,
345346
pin: TX,
346-
_word: PhantomData<WORD>,
347347
}
348348

349349
impl<USART: Instance, RX, WORD> URx<USART, RX, WORD> {
350350
fn new(pin: RX) -> Self {
351351
Self {
352-
_usart: PhantomData,
352+
inner: Rx::new(),
353353
pin,
354-
_word: PhantomData,
355354
}
356355
}
357356

358357
pub fn erase(self) -> Rx<USART, WORD> {
359358
Rx::new()
360359
}
361360

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();
361+
pub fn join<TX>(self, tx: UTx<USART, TX, WORD>) -> Serial<USART, (TX, RX), WORD>
362+
where
363+
(TX, RX): Pins<USART>,
364+
{
365+
Serial {
366+
usart: tx.usart,
367+
pins: (tx.pin, self.pin),
368+
tx: tx.inner,
369+
rx: self.inner,
403370
}
404371
}
405372
}
406373

407374
impl<USART: Instance, TX, WORD> UTx<USART, TX, WORD> {
408375
fn new(usart: USART, pin: TX) -> Self {
409376
Self {
377+
inner: Tx::new(),
410378
usart,
411379
pin,
412-
_word: PhantomData,
413380
}
414381
}
415382

@@ -424,28 +391,59 @@ impl<USART: Instance, TX, WORD> UTx<USART, TX, WORD> {
424391
Serial {
425392
usart: self.usart,
426393
pins: (self.pin, rx.pin),
427-
tx: Tx::new(),
428-
rx: Rx::new(),
394+
tx: self.inner,
395+
rx: rx.inner,
429396
}
430397
}
398+
}
431399

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()) }
400+
impl<USART, TX, WORD> AsRef<Tx<USART, WORD>> for UTx<USART, TX, WORD> {
401+
fn as_ref(&self) -> &Tx<USART, WORD> {
402+
&self.inner
439403
}
404+
}
440405

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()) }
406+
impl<USART, TX, WORD> Deref for UTx<USART, TX, WORD> {
407+
type Target = Tx<USART, WORD>;
408+
fn deref(&self) -> &Self::Target {
409+
&self.inner
444410
}
411+
}
445412

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() }
413+
impl<USART, RX, WORD> AsRef<Rx<USART, WORD>> for URx<USART, RX, WORD> {
414+
fn as_ref(&self) -> &Rx<USART, WORD> {
415+
&self.inner
416+
}
417+
}
418+
419+
impl<USART, RX, WORD> Deref for URx<USART, RX, WORD> {
420+
type Target = Rx<USART, WORD>;
421+
fn deref(&self) -> &Self::Target {
422+
&self.inner
423+
}
424+
}
425+
426+
impl<USART, TX, WORD> AsMut<Tx<USART, WORD>> for UTx<USART, TX, WORD> {
427+
fn as_mut(&mut self) -> &mut Tx<USART, WORD> {
428+
&mut self.inner
429+
}
430+
}
431+
432+
impl<USART, TX, WORD> DerefMut for UTx<USART, TX, WORD> {
433+
fn deref_mut(&mut self) -> &mut Self::Target {
434+
&mut self.inner
435+
}
436+
}
437+
438+
impl<USART, RX, WORD> AsMut<Rx<USART, WORD>> for URx<USART, RX, WORD> {
439+
fn as_mut(&mut self) -> &mut Rx<USART, WORD> {
440+
&mut self.inner
441+
}
442+
}
443+
444+
impl<USART, RX, WORD> DerefMut for URx<USART, RX, WORD> {
445+
fn deref_mut(&mut self) -> &mut Self::Target {
446+
&mut self.inner
449447
}
450448
}
451449

@@ -1035,109 +1033,3 @@ impl<USART: Instance> Tx<USART, u16> {
10351033
nb::block!(self.flush())
10361034
}
10371035
}
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)