Skip to content

Commit 3abe07d

Browse files
bors[bot]burrbull
andauthored
Merge #447
447: Unify serial trait impls for embedded-hal 0.2 & 1.0 r=therealprof a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents a368c2d + 4aa48f5 commit 3abe07d

File tree

4 files changed

+144
-227
lines changed

4 files changed

+144
-227
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Changed
1111

12+
- Unify serial trait impls for embedded-hal 0.2 & 1.0
1213
- Add possibility to select Timer master mode
1314
- Add inherent impl of `embedded_hal::Pwm` methods on `Pwm`s [#439]
1415
- Use `embedded-dma` v0.2 [#440]

src/serial.rs

Lines changed: 101 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,7 @@ use crate::rcc::Clocks;
3535
use crate::dma::traits::PeriAddress;
3636

3737
/// Serial error
38-
#[non_exhaustive]
39-
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
40-
pub enum Error {
41-
/// Framing error
42-
Framing,
43-
/// Noise error
44-
Noise,
45-
/// RX buffer overrun
46-
Overrun,
47-
/// Parity check error
48-
Parity,
49-
}
38+
pub use embedded_hal_one::serial::ErrorKind as Error;
5039

5140
/// Interrupt event
5241
pub enum Event {
@@ -766,23 +755,114 @@ halUsart! { pac::UART9, Serial9, Rx9, Tx9 }
766755
#[cfg(feature = "uart10")]
767756
halUsart! { pac::UART10, Serial10, Rx10, Tx10 }
768757

769-
impl<USART, PINS> fmt::Write for Serial<USART, PINS>
770-
where
771-
Tx<USART>: embedded_hal::serial::Write<u8>,
772-
{
758+
impl<USART: Instance, PINS> fmt::Write for Serial<USART, PINS> {
773759
fn write_str(&mut self, s: &str) -> fmt::Result {
774760
self.tx.write_str(s)
775761
}
776762
}
777763

778-
impl<USART> fmt::Write for Tx<USART>
779-
where
780-
Tx<USART>: embedded_hal::serial::Write<u8>,
781-
{
764+
impl<USART: Instance> fmt::Write for Tx<USART> {
782765
fn write_str(&mut self, s: &str) -> fmt::Result {
783-
use embedded_hal::serial::Write;
784766
s.bytes()
785767
.try_for_each(|c| block!(self.write(c)))
786768
.map_err(|_| fmt::Error)
787769
}
788770
}
771+
772+
impl<USART: Instance> Rx<USART, u8> {
773+
fn read(&mut self) -> nb::Result<u8, Error> {
774+
// Delegate to the Read<u16> implementation, then truncate to 8 bits
775+
Rx::<USART, u16>::new().read().map(|word16| word16 as u8)
776+
}
777+
}
778+
779+
impl<USART: Instance> Rx<USART, u16> {
780+
fn read(&mut self) -> nb::Result<u16, Error> {
781+
// NOTE(unsafe) atomic read with no side effects
782+
let sr = unsafe { (*USART::ptr()).sr.read() };
783+
784+
// Any error requires the dr to be read to clear
785+
if sr.pe().bit_is_set()
786+
|| sr.fe().bit_is_set()
787+
|| sr.nf().bit_is_set()
788+
|| sr.ore().bit_is_set()
789+
{
790+
unsafe { (*USART::ptr()).dr.read() };
791+
}
792+
793+
Err(if sr.pe().bit_is_set() {
794+
Error::Parity.into()
795+
} else if sr.fe().bit_is_set() {
796+
Error::FrameFormat.into()
797+
} else if sr.nf().bit_is_set() {
798+
Error::Noise.into()
799+
} else if sr.ore().bit_is_set() {
800+
Error::Overrun.into()
801+
} else if sr.rxne().bit_is_set() {
802+
// NOTE(unsafe) atomic read from stateless register
803+
return Ok(unsafe { &*USART::ptr() }.dr.read().dr().bits());
804+
} else {
805+
nb::Error::WouldBlock
806+
})
807+
}
808+
}
809+
810+
impl<USART: Instance> Tx<USART, u8> {
811+
fn write(&mut self, word: u8) -> nb::Result<(), Error> {
812+
// Delegate to u16 version
813+
Tx::<USART, u16>::new().write(u16::from(word))
814+
}
815+
816+
fn flush(&mut self) -> nb::Result<(), Error> {
817+
// Delegate to u16 version
818+
Tx::<USART, u16>::new().flush()
819+
}
820+
821+
fn bwrite_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
822+
for &b in bytes {
823+
nb::block!(self.write(b))?;
824+
}
825+
Ok(())
826+
}
827+
828+
fn bflush(&mut self) -> Result<(), Error> {
829+
nb::block!(self.flush())
830+
}
831+
}
832+
833+
impl<USART: Instance> Tx<USART, u16> {
834+
fn write(&mut self, word: u16) -> nb::Result<(), Error> {
835+
// NOTE(unsafe) atomic read with no side effects
836+
let sr = unsafe { (*USART::ptr()).sr.read() };
837+
838+
if sr.txe().bit_is_set() {
839+
// NOTE(unsafe) atomic write to stateless register
840+
unsafe { &*USART::ptr() }.dr.write(|w| w.dr().bits(word));
841+
Ok(())
842+
} else {
843+
Err(nb::Error::WouldBlock)
844+
}
845+
}
846+
847+
fn flush(&mut self) -> nb::Result<(), Error> {
848+
// NOTE(unsafe) atomic read with no side effects
849+
let sr = unsafe { (*USART::ptr()).sr.read() };
850+
851+
if sr.tc().bit_is_set() {
852+
Ok(())
853+
} else {
854+
Err(nb::Error::WouldBlock)
855+
}
856+
}
857+
858+
fn bwrite_all(&mut self, buffer: &[u16]) -> Result<(), Error> {
859+
for &b in buffer {
860+
nb::block!(self.write(b))?;
861+
}
862+
Ok(())
863+
}
864+
865+
fn bflush(&mut self) -> Result<(), Error> {
866+
nb::block!(self.flush())
867+
}
868+
}

src/serial/hal_02.rs

Lines changed: 16 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ mod nb {
99
{
1010
type Error = Error;
1111

12-
fn read(&mut self) -> nb::Result<WORD, Error> {
12+
fn read(&mut self) -> nb::Result<WORD, Self::Error> {
1313
self.rx.read()
1414
}
1515
}
@@ -18,8 +18,7 @@ mod nb {
1818
type Error = Error;
1919

2020
fn read(&mut self) -> nb::Result<u8, Self::Error> {
21-
// Delegate to the Read<u16> implementation, then truncate to 8 bits
22-
Rx::<USART, u16>::new().read().map(|word16| word16 as u8)
21+
self.read()
2322
}
2423
}
2524

@@ -31,33 +30,8 @@ mod nb {
3130
impl<USART: Instance> Read<u16> for Rx<USART, u16> {
3231
type Error = Error;
3332

34-
fn read(&mut self) -> nb::Result<u16, Error> {
35-
// NOTE(unsafe) atomic read with no side effects
36-
let sr = unsafe { (*USART::ptr()).sr.read() };
37-
38-
// Any error requires the dr to be read to clear
39-
if sr.pe().bit_is_set()
40-
|| sr.fe().bit_is_set()
41-
|| sr.nf().bit_is_set()
42-
|| sr.ore().bit_is_set()
43-
{
44-
unsafe { (*USART::ptr()).dr.read() };
45-
}
46-
47-
Err(if sr.pe().bit_is_set() {
48-
Error::Parity.into()
49-
} else if sr.fe().bit_is_set() {
50-
Error::Framing.into()
51-
} else if sr.nf().bit_is_set() {
52-
Error::Noise.into()
53-
} else if sr.ore().bit_is_set() {
54-
Error::Overrun.into()
55-
} else if sr.rxne().bit_is_set() {
56-
// NOTE(unsafe) atomic read from stateless register
57-
return Ok(unsafe { &*USART::ptr() }.dr.read().dr().bits());
58-
} else {
59-
nb::Error::WouldBlock
60-
})
33+
fn read(&mut self) -> nb::Result<u16, Self::Error> {
34+
self.read()
6135
}
6236
}
6337

@@ -81,13 +55,11 @@ mod nb {
8155
type Error = Error;
8256

8357
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
84-
// Delegate to u16 version
85-
Tx::<USART, u16>::new().write(u16::from(word))
58+
self.write(word)
8659
}
8760

8861
fn flush(&mut self) -> nb::Result<(), Self::Error> {
89-
// Delegate to u16 version
90-
Tx::<USART, u16>::new().flush()
62+
self.flush()
9163
}
9264
}
9365

@@ -100,59 +72,28 @@ mod nb {
10072
type Error = Error;
10173

10274
fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
103-
// NOTE(unsafe) atomic read with no side effects
104-
let sr = unsafe { (*USART::ptr()).sr.read() };
105-
106-
if sr.txe().bit_is_set() {
107-
// NOTE(unsafe) atomic write to stateless register
108-
unsafe { &*USART::ptr() }.dr.write(|w| w.dr().bits(word));
109-
Ok(())
110-
} else {
111-
Err(nb::Error::WouldBlock)
112-
}
75+
self.write(word)
11376
}
11477

11578
fn flush(&mut self) -> nb::Result<(), Self::Error> {
116-
// NOTE(unsafe) atomic read with no side effects
117-
let sr = unsafe { (*USART::ptr()).sr.read() };
118-
119-
if sr.tc().bit_is_set() {
120-
Ok(())
121-
} else {
122-
Err(nb::Error::WouldBlock)
123-
}
79+
self.flush()
12480
}
12581
}
12682
}
12783

12884
mod blocking {
12985
use super::super::{Error, Instance, Serial, Tx};
130-
use embedded_hal::{blocking::serial::Write, serial};
86+
use embedded_hal::blocking::serial::Write;
13187

13288
impl<USART: Instance> Write<u8> for Tx<USART, u8> {
13389
type Error = Error;
13490

13591
fn bwrite_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
136-
for &b in bytes {
137-
loop {
138-
match <Self as serial::Write<u8>>::write(self, b) {
139-
Err(nb::Error::WouldBlock) => continue,
140-
Err(nb::Error::Other(err)) => return Err(err),
141-
Ok(()) => break,
142-
}
143-
}
144-
}
145-
Ok(())
92+
self.bwrite_all(bytes)
14693
}
14794

14895
fn bflush(&mut self) -> Result<(), Self::Error> {
149-
loop {
150-
match <Self as serial::Write<u8>>::flush(self) {
151-
Ok(()) => return Ok(()),
152-
Err(nb::Error::WouldBlock) => continue,
153-
Err(nb::Error::Other(err)) => return Err(err),
154-
}
155-
}
96+
self.bflush()
15697
}
15798
}
15899

@@ -171,35 +112,20 @@ mod blocking {
171112
impl<USART: Instance> Write<u16> for Tx<USART, u16> {
172113
type Error = Error;
173114

174-
fn bwrite_all(&mut self, buffer: &[u16]) -> Result<(), Self::Error> {
175-
for &b in buffer {
176-
loop {
177-
match <Self as serial::Write<u16>>::write(self, b) {
178-
Err(nb::Error::WouldBlock) => continue,
179-
Err(nb::Error::Other(err)) => return Err(err),
180-
Ok(()) => break,
181-
}
182-
}
183-
}
184-
Ok(())
115+
fn bwrite_all(&mut self, slice: &[u16]) -> Result<(), Self::Error> {
116+
self.bwrite_all(slice)
185117
}
186118

187119
fn bflush(&mut self) -> Result<(), Self::Error> {
188-
loop {
189-
match <Self as serial::Write<u16>>::flush(self) {
190-
Ok(()) => return Ok(()),
191-
Err(nb::Error::WouldBlock) => continue,
192-
Err(nb::Error::Other(err)) => return Err(err),
193-
}
194-
}
120+
self.bflush()
195121
}
196122
}
197123

198124
impl<USART: Instance, PINS> Write<u16> for Serial<USART, PINS, u16> {
199125
type Error = Error;
200126

201-
fn bwrite_all(&mut self, bytes: &[u16]) -> Result<(), Self::Error> {
202-
self.tx.bwrite_all(bytes)
127+
fn bwrite_all(&mut self, slice: &[u16]) -> Result<(), Self::Error> {
128+
self.tx.bwrite_all(slice)
203129
}
204130

205131
fn bflush(&mut self) -> Result<(), Self::Error> {

0 commit comments

Comments
 (0)