atsamd_hal/sercom/uart/
flags.rs

1//! Flag definitions
2
3use bitflags::bitflags;
4
5//=============================================================================
6// Interrupt flags
7//=============================================================================
8const DRE: u8 = 0x01;
9const TXC: u8 = 0x02;
10const RXC: u8 = 0x04;
11const RXS: u8 = 0x08;
12pub(super) const CTSIC: u8 = 0x10;
13const RXBRK: u8 = 0x20;
14const ERROR: u8 = 0x80;
15
16/// Interrupt flags available for RX transactions
17pub const RX_FLAG_MASK: u8 = RXC | RXS | RXBRK | ERROR;
18/// Interrupt flags available for TX transactions
19pub const TX_FLAG_MASK: u8 = DRE | TXC;
20/// Interrupt flags available for Duplex transactions
21pub const DUPLEX_FLAG_MASK: u8 = RX_FLAG_MASK | TX_FLAG_MASK;
22
23bitflags! {
24    /// Interrupt bit flags for UART Rx transactions
25    ///
26    /// The available interrupt flags are `DRE`, `TXC`, `RXC`, `RXS`, `CTSIC`, `RXBRK` and
27    /// `ERROR`. The binary format of the underlying bits exactly matches the
28    /// INTFLAG bits.
29    #[derive(Clone, Copy)]
30    pub struct Flags: u8 {
31        const DRE = DRE;
32        const TXC = TXC;
33        const RXC = RXC;
34        const RXS = RXS ;
35        const CTSIC = CTSIC;
36        const RXBRK = RXBRK;
37        const ERROR = ERROR;
38    }
39}
40
41impl Flags {
42    /// [`Flags`] which can be used for receiving
43    pub const RX: Self = Self::from_bits_retain(RX_FLAG_MASK);
44
45    /// [`Flags`] which can be used for transmitting
46    pub const TX: Self = Self::from_bits_retain(TX_FLAG_MASK);
47}
48
49//=============================================================================
50// Status flags
51//=============================================================================
52
53const PERR: u16 = 0x01;
54const FERR: u16 = 0x02;
55const BUFOVF: u16 = 0x04;
56const CTS: u16 = 0x08;
57const ISF: u16 = 0x10;
58const COLL: u16 = 0x20;
59
60/// Status flags available for RX transactions
61pub const RX_STATUS_MASK: u16 = PERR | FERR | BUFOVF | ISF | COLL;
62/// Status flags available for Duplex transactions
63pub const DUPLEX_STATUS_MASK: u16 = RX_STATUS_MASK;
64
65bitflags! {
66    /// Status flags for UART Rx transactions
67    ///
68    /// The available status flags are `PERR`, `FERR`, `BUFOVF`,
69    /// `CTS`, `ISF` and `COLL`.
70    /// The binary format of the underlying bits exactly matches
71    /// the STATUS bits.
72    pub struct Status: u16 {
73        const PERR = PERR;
74        const FERR = FERR;
75        const BUFOVF = BUFOVF;
76        const CTS = CTS;
77        const ISF = ISF;
78        const COLL = COLL;
79    }
80}
81
82impl Status {
83    /// Check whether [`Self`] originates from an error.
84    ///
85    /// # Errors
86    ///
87    /// Returns an error if `STATUS` contains:
88    ///
89    /// * `PERR` - Parity error
90    /// * `FERR` - Frame error
91    /// * `BUFOVF` - Buffer overflow
92    /// * `ISF` - Inconsistent SYNC field
93    /// * `COLL` - Collision
94    #[inline]
95    pub fn check_bus_error(self) -> Result<(), Error> {
96        use Error::*;
97        if self.contains(Status::PERR) {
98            Err(ParityError)
99        } else if self.contains(Status::FERR) {
100            Err(FrameError)
101        } else if self.contains(Status::BUFOVF) {
102            Err(Overflow)
103        } else if self.contains(Status::ISF) {
104            Err(InconsistentSyncField)
105        } else if self.contains(Status::COLL) {
106            Err(CollisionDetected)
107        } else {
108            Ok(())
109        }
110    }
111}
112
113//=============================================================================
114// Error
115//=============================================================================
116
117/// Errors available for UART transactions
118#[derive(Debug, Clone, Copy, Eq, PartialEq)]
119#[cfg_attr(feature = "defmt", derive(defmt::Format))]
120pub enum Error {
121    /// Detected a parity error
122    ParityError,
123    /// Detected a frame error
124    FrameError,
125    /// Detected a buffer overflow
126    Overflow,
127    /// Detected an inconsistent sync field
128    InconsistentSyncField,
129    /// Detected a collision
130    CollisionDetected,
131    /// DMA error
132    #[cfg(feature = "dma")]
133    Dma(crate::dmac::Error),
134}
135
136impl From<Error> for Status {
137    #[inline]
138    fn from(err: Error) -> Self {
139        use Error::*;
140        match err {
141            ParityError => Status::PERR,
142            FrameError => Status::FERR,
143            Overflow => Status::BUFOVF,
144            InconsistentSyncField => Status::ISF,
145            CollisionDetected => Status::COLL,
146            #[cfg(feature = "dma")]
147            Dma(_) => unimplemented!(),
148        }
149    }
150}