axi_uart16550/regs.rs
1//! # Raw register module
2
3/// Register field types.
4pub mod fields {
5 use arbitrary_int::u2;
6
7 /// Transmitter Holding Register.
8 #[bitbybit::bitfield(u32, defmt_bitfields(feature = "defmt"))]
9 pub struct Fifo {
10 /// Bytes to transmit or receive.
11 #[bits(0..=7, rw)]
12 data: u8,
13 }
14
15 /// Interrupt Enable Register.
16 #[bitbybit::bitfield(u32, defmt_bitfields(feature = "defmt"))]
17 pub struct InterruptEnable {
18 /// Enable Modem Status Interrupt
19 #[bit(3, rw)]
20 modem_status: bool,
21 /// Enable Receiver Line Status Interrupt
22 #[bit(2, rw)]
23 line_status: bool,
24 /// Enable Transmitter Holding Register Empty Interrupt
25 #[bit(1, rw)]
26 thr_empty: bool,
27 /// Enable Received Data Available Interrupt
28 #[bit(0, rw)]
29 rx_avl: bool,
30 }
31
32 /// Interrupt identification ID
33 #[bitbybit::bitenum(u3, exhaustive = false)]
34 #[derive(Debug, PartialEq, Eq)]
35 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
36 pub enum InterruptId2 {
37 /// Receiver Line Status.
38 ReceiverLineStatus = 0b011,
39 /// RX data available.
40 RxDataAvailable = 0b010,
41 /// Character timeout.
42 CharTimeout = 0b110,
43 /// THR empty.
44 ThrEmpty = 0b001,
45 /// Modem status.
46 ModemStatus = 0b000,
47 }
48
49 /// Interrupt Identification Register
50 #[bitbybit::bitfield(u32, defmt_bitfields(feature = "defmt"))]
51 pub struct InterruptIdentification {
52 /// 16550 mode enabled?
53 #[bits(6..=7, r)]
54 fifo_enabled: u2,
55 /// Interrupt ID2.
56 #[bits(1..=3, r)]
57 int_id: Option<InterruptId2>,
58 /// Interrupt Pending, active low.
59 #[bit(0, r)]
60 int_pend_n: bool,
61 }
62
63 /// RX FIFO trigger level.
64 #[bitbybit::bitenum(u2, exhaustive = true)]
65 #[derive(Debug, PartialEq, Eq)]
66 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
67 pub enum RxFifoTrigger {
68 /// One byte.
69 OneByte = 0b00,
70 /// 4 bytes.
71 FourBytes = 0b01,
72 /// 8 bytes.
73 EightBytes = 0b10,
74 /// 14 bytes.
75 FourteenBytes = 0b11,
76 }
77
78 impl RxFifoTrigger {
79 /// Raw number instead of register value.
80 pub const fn as_num(self) -> u32 {
81 match self {
82 RxFifoTrigger::OneByte => 1,
83 RxFifoTrigger::FourBytes => 4,
84 RxFifoTrigger::EightBytes => 8,
85 RxFifoTrigger::FourteenBytes => 14,
86 }
87 }
88 }
89
90 /// FIFO Control Register
91 #[bitbybit::bitfield(u32, default = 0x0, defmt_bitfields(feature = "defmt"))]
92 pub struct FifoControl {
93 /// RX FIFO trigger level.
94 #[bits(4..=5, rw)]
95 rx_fifo_trigger: RxFifoTrigger,
96 /// DMA mode select.
97 #[bit(3, rw)]
98 dma_mode_sel: bool,
99 /// Reset TX FIFO.
100 #[bit(2, rw)]
101 reset_tx_fifo: bool,
102 /// Reset RX FIFO.
103 #[bit(1, rw)]
104 reset_rx_fifo: bool,
105 /// FIFO enable.
106 #[bit(0, rw)]
107 fifo_enable: bool,
108 }
109
110 /// Word length in bits.
111 #[bitbybit::bitenum(u2, exhaustive = true)]
112 #[derive(Default, Debug, PartialEq, Eq)]
113 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
114 pub enum WordLen {
115 /// 5 bits.
116 Five = 0b00,
117 /// 6 bits.
118 Six = 0b01,
119 /// 7 bits.
120 Seven = 0b10,
121 /// 8 bits (default).
122 #[default]
123 Eight = 0b11,
124 }
125
126 /// Stop bits.
127 #[bitbybit::bitenum(u1, exhaustive = true)]
128 #[derive(Default, Debug, PartialEq, Eq)]
129 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
130 pub enum StopBits {
131 /// One stop bit (default).
132 #[default]
133 One = 0b0,
134 /// 1.5 for 5 bits/char, 2 otherwise.
135 OnePointFiveOrTwo = 0b1,
136 }
137
138 /// Line control register.
139 #[bitbybit::bitfield(u32, default = 0x00, defmt_bitfields(feature = "defmt"))]
140 pub struct LineControl {
141 /// Divisor Latch Access Bit.
142 #[bit(7, rw)]
143 div_access_latch: bool,
144 /// Set break bit.
145 #[bit(6, rw)]
146 set_break: bool,
147 /// Parity stick bit.
148 #[bit(5, rw)]
149 stick_parity: bool,
150 /// Even parity.
151 #[bit(4, rw)]
152 even_parity: bool,
153 /// Parity enable.
154 #[bit(3, rw)]
155 parity_enable: bool,
156 /// 0: 1 stop bit, 1: 2 stop bits or 1.5 if 5 bits/char selected
157 #[bit(2, rw)]
158 stop_bits: StopBits,
159 /// Word length.
160 #[bits(0..=1, rw)]
161 word_len: WordLen,
162 }
163
164 impl LineControl {
165 /// New line control value for accessing divisor latches.
166 pub fn new_for_divisor_access() -> Self {
167 Self::new_with_raw_value(0x80)
168 }
169 }
170
171 /// Line Status Register
172 #[bitbybit::bitfield(u32, defmt_bitfields(feature = "defmt"))]
173 #[derive(Debug)]
174 pub struct LineStatus {
175 /// Error in RX FIFO.
176 #[bit(7, rw)]
177 error_in_rx_fifo: bool,
178 /// In the FIFO mode, this is set to 1 when the TX FIFO and shift register are both empty.
179 #[bit(6, rw)]
180 tx_empty: bool,
181 /// In the FIFO mode, this is set to 1 when the TX FIFO is empty. There might still be a byte
182 /// in the TX shift register.
183 #[bit(5, rw)]
184 thr_empty: bool,
185 /// Break interrupt.
186 #[bit(4, rw)]
187 break_interrupt: bool,
188 /// Framing error.
189 #[bit(3, rw)]
190 framing_error: bool,
191 /// Parity error.
192 #[bit(2, rw)]
193 parity_error: bool,
194 /// Overrun error.
195 #[bit(1, rw)]
196 overrun_error: bool,
197 /// Data ready.
198 #[bit(0, rw)]
199 data_ready: bool,
200 }
201}
202
203/// Raw register block.
204#[derive(derive_mmio::Mmio)]
205#[repr(C)]
206pub struct Registers {
207 _reserved: [u32; 0x400],
208 /// FIFO register for LCR[7] == 0 or Divisor Latch (LSB) register for LCR[7] == 1
209 fifo_or_dll: u32,
210 /// Interrupt Enable Register for LCR[7] == 0 or Divisor Latch (MSB) register for LCR[7] == 1
211 ier_or_dlm: u32,
212 /// Interrupt Identification Register or FIFO Control Register. FCR is not included in 16450
213 /// mode. If LCR[7] == 1, this register will be the read-only FIFO control register.
214 /// If LCR[7] == 0, this register will be the read-only interrupt IIR register or the
215 /// write-only FIFO control register.
216 iir_or_fcr: u32,
217 /// Line Control Register
218 lcr: fields::LineControl,
219 /// Modem Control Register
220 mcr: u32,
221 /// Line Status Register
222 lsr: fields::LineStatus,
223 /// Modem Status Register
224 msr: u32,
225 /// Scratch Register
226 scr: u32,
227}