1//! Serial interface.
23/// Serial error.
4pub trait Error: core::fmt::Debug {
5/// Convert error to a generic serial error kind
6 ///
7 /// By using this method, serial errors freely defined by HAL implementations
8 /// can be converted to a set of generic serial errors upon which generic
9 /// code can act.
10fn kind(&self) -> ErrorKind;
11}
1213impl Error for core::convert::Infallible {
14#[inline]
15fn kind(&self) -> ErrorKind {
16match *self {}
17 }
18}
1920/// Serial error kind.
21///
22/// This represents a common set of serial operation errors. HAL implementations are
23/// free to define more specific or additional error types. However, by providing
24/// a mapping to these common serial errors, generic code can still react to them.
25#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
26#[non_exhaustive]
27pub enum ErrorKind {
28/// The peripheral receive buffer was overrun.
29Overrun,
30/// Received data does not conform to the peripheral configuration.
31 /// Can be caused by a misconfigured device on either end of the serial line.
32FrameFormat,
33/// Parity check failed.
34Parity,
35/// Serial line is too noisy to read valid data.
36Noise,
37/// A different error occurred. The original error may contain more information.
38Other,
39}
4041impl Error for ErrorKind {
42#[inline]
43fn kind(&self) -> ErrorKind {
44*self
45}
46}
4748impl core::fmt::Display for ErrorKind {
49#[inline]
50fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51match self {
52Self::Overrun => write!(f, "The peripheral receive buffer was overrun"),
53Self::Parity => write!(f, "Parity check failed"),
54Self::Noise => write!(f, "Serial line is too noisy to read valid data"),
55Self::FrameFormat => write!(
56 f,
57"Received data does not conform to the peripheral configuration"
58),
59Self::Other => write!(
60 f,
61"A different error occurred. The original error may contain more information"
62),
63 }
64 }
65}
6667/// Serial error type trait.
68///
69/// This just defines the error type, to be used by the other traits.
70pub trait ErrorType {
71/// Error type
72type Error: Error;
73}
7475impl<T: ErrorType + ?Sized> ErrorType for &mut T {
76type Error = T::Error;
77}
7879/// Read half of a serial interface.
80///
81/// Some serial interfaces support different data sizes (8 bits, 9 bits, etc.);
82/// This can be encoded in this trait via the `Word` type parameter.
83pub trait Read<Word: Copy = u8>: ErrorType {
84/// Reads a single word from the serial interface
85fn read(&mut self) -> nb::Result<Word, Self::Error>;
86}
8788impl<T: Read<Word> + ?Sized, Word: Copy> Read<Word> for &mut T {
89#[inline]
90fn read(&mut self) -> nb::Result<Word, Self::Error> {
91 T::read(self)
92 }
93}
9495/// Write half of a serial interface.
96pub trait Write<Word: Copy = u8>: ErrorType {
97/// Writes a single word to the serial interface.
98fn write(&mut self, word: Word) -> nb::Result<(), Self::Error>;
99100/// Ensures that none of the previously written words are still buffered.
101fn flush(&mut self) -> nb::Result<(), Self::Error>;
102}
103104impl<T: Write<Word> + ?Sized, Word: Copy> Write<Word> for &mut T {
105#[inline]
106fn write(&mut self, word: Word) -> nb::Result<(), Self::Error> {
107 T::write(self, word)
108 }
109110#[inline]
111fn flush(&mut self) -> nb::Result<(), Self::Error> {
112 T::flush(self)
113 }
114}
115116/// Implementation of `core::fmt::Write` for the HAL's `serial::Write`.
117///
118/// TODO write example of usage
119120impl<Word, Error: self::Error> core::fmt::Write for dyn Write<Word, Error = Error> + '_
121where
122Word: Copy + From<u8>,
123{
124#[inline]
125fn write_str(&mut self, s: &str) -> core::fmt::Result {
126let _ = s
127 .bytes()
128 .map(|c| nb::block!(self.write(Word::from(c))))
129 .last();
130Ok(())
131 }
132}