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}