Skip to content

Commit dc4d0cd

Browse files
Correctly return serial error when they occur
1 parent 68eeba6 commit dc4d0cd

File tree

1 file changed

+23
-32
lines changed

1 file changed

+23
-32
lines changed

src/serial.rs

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub use crate::{
2828
gpio::gpiob::*,
2929
gpio::gpioc::*,
3030
gpio::gpiod::*,
31-
gpio::gpioe::*,
31+
gpio::gpioe::*,
3232
pac::{LPUART1, USART1, USART4, USART5},
3333
};
3434

@@ -181,7 +181,7 @@ impl_pins!(
181181
USART4, PC10, PC11, AF6;
182182
USART4, PE8, PE9, AF6;
183183
USART5, PB3, PB4, AF6;
184-
USART5, PE10, PE11, AF6;
184+
USART5, PE10, PE11, AF6;
185185
);
186186

187187
/// Serial abstraction
@@ -425,42 +425,33 @@ macro_rules! usart {
425425
fn read(&mut self) -> nb::Result<u8, Error> {
426426
// NOTE(unsafe) atomic read with no side effects
427427
let isr = unsafe { (*$USARTX::ptr()).isr.read() };
428+
let icr = unsafe { &(*$USARTX::ptr()).icr };
428429

429-
// Check for any errors
430-
let _err = if isr.pe().bit_is_set() {
431-
Some(Error::Parity)
430+
// Check for errors. We don't want to drop errors, so check each error bit in
431+
// sequence. If any bit is set, clear it and return its error.
432+
if isr.pe().bit_is_set() {
433+
icr.write(|w| {w.pecf().set_bit()});
434+
return Err(Error::Parity.into());
432435
} else if isr.fe().bit_is_set() {
433-
Some(Error::Framing)
436+
icr.write(|w| {w.fecf().set_bit()});
437+
return Err(Error::Framing.into());
434438
} else if isr.nf().bit_is_set() {
435-
Some(Error::Noise)
439+
icr.write(|w| {w.ncf().set_bit()});
440+
return Err(Error::Noise.into());
436441
} else if isr.ore().bit_is_set() {
437-
Some(Error::Overrun)
438-
} else {
439-
None
440-
};
442+
icr.write(|w| {w.orecf().set_bit()});
443+
return Err(Error::Overrun.into());
444+
}
441445

442-
if let Some(_err) = _err {
443-
// Some error occured. Clear the error flags by writing to ICR
444-
// followed by a read from the rdr register
446+
// Check if a byte is available
447+
if isr.rxne().bit_is_set() {
448+
// Read the received byte
445449
// NOTE(read_volatile) see `write_volatile` below
446-
unsafe {
447-
(*$USARTX::ptr()).icr.write(|w| {w.pecf().set_bit()});
448-
(*$USARTX::ptr()).icr.write(|w| {w.fecf().set_bit()});
449-
(*$USARTX::ptr()).icr.write(|w| {w.ncf().set_bit()});
450-
(*$USARTX::ptr()).icr.write(|w| {w.orecf().set_bit()});
451-
}
452-
Err(nb::Error::WouldBlock)
450+
Ok(unsafe {
451+
ptr::read_volatile(&(*$USARTX::ptr()).rdr as *const _ as *const _)
452+
})
453453
} else {
454-
// Check if a byte is available
455-
if isr.rxne().bit_is_set() {
456-
// Read the received byte
457-
// NOTE(read_volatile) see `write_volatile` below
458-
Ok(unsafe {
459-
ptr::read_volatile(&(*$USARTX::ptr()).rdr as *const _ as *const _)
460-
})
461-
} else {
462-
Err(nb::Error::WouldBlock)
463-
}
454+
Err(nb::Error::WouldBlock)
464455
}
465456
}
466457
}
@@ -569,7 +560,7 @@ usart! {
569560
USART1: (usart1, apb2enr, usart1en, apb1_clk, Serial1Ext),
570561
USART2: (usart2, apb1enr, usart2en, apb1_clk, Serial2Ext),
571562
USART4: (usart4, apb1enr, usart4en, apb1_clk, Serial4Ext),
572-
USART5: (usart5, apb1enr, usart5en, apb1_clk, Serial5Ext),
563+
USART5: (usart5, apb1enr, usart5en, apb1_clk, Serial5Ext),
573564
}
574565

575566
impl<USART> fmt::Write for Serial<USART>

0 commit comments

Comments
 (0)