uart_xilinx/uart_16550/
uart.rs1#[cfg(feature = "fmt")]
2use core::fmt;
3
4use super::registers::Registers;
5
6bitflags! {
7 pub struct IER: u8 {
9 const RDAI = 0b0000_0001;
11 const THREI = 0b0000_0010;
13 const RLSI = 0b0000_0100;
15 const MSI = 0b0000_1000;
17 }
18}
19
20bitflags! {
21 pub struct LSR: u8 {
23 const DR = 0b0000_0001;
25 const OE = 0b0000_0010;
27 const PE = 0b0000_0100;
29 const FE = 0b0000_1000;
31 const BI = 0b0001_0000;
33 const THRE = 0b0010_0000;
35 const DHRE = 0b0100_0000;
37 const RFE = 0b1000_0000;
39 }
40}
41
42bitflags! {
43 pub struct MSR: u8 {
45 const DCTS = 0b0000_0001;
47 const DDSR = 0b0000_0010;
49 const TERI = 0b0000_0100;
51 const DDCD = 0b0000_1000;
53 const CTS = 0b0001_0000;
55 const DSR = 0b0010_0000;
57 const RI = 0b0100_0000;
59 const CD = 0b1000_0000;
61 }
62}
63
64#[derive(Debug, Clone, PartialEq)]
65pub enum InterruptType {
66 ModemStatus,
67 TransmitterHoldingRegisterEmpty,
68 ReceivedDataAvailable,
69 ReceiverLineStatus,
70 Timeout,
71 Reserved,
72}
73
74#[derive(Debug, Clone, PartialEq)]
75pub enum Parity {
76 No,
77 Odd,
78 Even,
79 Mark,
80 Space,
81}
82
83pub struct MmioUartAxi16550<'a> {
87 reg: &'a mut Registers,
88}
89
90impl<'a> MmioUartAxi16550<'a> {
91 pub fn new(base_address: usize) -> Self {
93 Self {
94 reg: cast!(base_address),
95 }
96 }
97
98 pub fn init(&self, clock: usize, baud_rate: usize) {
102 self.set_divisor(clock, baud_rate);
104
105 self.write_lcr(3);
107 self.write_fcr(1);
109 self.write_mcr(0);
111 self.enable_received_data_available_interrupt();
113 }
116
117 pub fn set_base_address(&mut self, base_address: usize) {
119 self.reg = cast!(base_address);
120 }
121
122 pub fn read_byte(&self) -> Option<u8> {
126 if self.is_data_ready() {
127 Some(self.read_rbr() as u8)
128 } else {
129 None
130 }
131 }
132
133 pub fn write_byte(&self, byte: u8) {
137 self.write_thr(byte as u32);
138 }
139
140 #[inline]
144 pub fn write_thr(&self, value: u32) {
145 unsafe { self.reg.rw[0].write(value) }
146 }
147
148 #[inline]
152 pub fn read_rbr(&self) -> u32 {
153 self.reg.rw[0].read()
154 }
155
156 #[inline]
160 pub fn read_dll(&self) -> u32 {
161 self.reg.rw[0].read()
162 }
163
164 #[inline]
168 pub fn write_dll(&self, value: u32) {
169 unsafe { self.reg.rw[0].write(value) }
170 }
171
172 #[inline]
176 pub fn read_dlh(&self) -> u32 {
177 self.reg.rw[1].read()
178 }
179
180 #[inline]
184 pub fn write_dlh(&self, value: u32) {
185 unsafe { self.reg.rw[1].write(value) }
186 }
187
188 #[inline]
190 pub fn set_divisor(&self, clock: usize, baud_rate: usize) {
191 self.enable_divisor_latch_accessible();
192 let divisor = clock / (16 * baud_rate);
193 self.write_dll((divisor & 0b1111_1111) as u32);
194 self.write_dlh(((divisor >> 8) & 0b1111_1111) as u32);
195 self.disable_divisor_latch_accessible();
196 }
197
198 #[inline]
202 pub fn read_ier(&self) -> u32 {
203 self.reg.rw[1].read()
204 }
205
206 #[inline]
210 pub fn write_ier(&self, value: u32) {
211 unsafe { self.reg.rw[1].write(value) }
212 }
213
214 #[inline]
216 pub fn ier(&self) -> IER {
217 IER::from_bits_truncate(self.read_ier() as u8)
218 }
219
220 #[inline]
222 pub fn set_ier(&self, flag: IER) {
223 self.write_ier(flag.bits() as u32)
224 }
225
226 pub fn is_modem_status_interrupt_enabled(&self) -> bool {
228 self.ier().contains(IER::MSI)
229 }
230
231 pub fn toggle_modem_status_interrupt(&self) {
233 self.set_ier(self.ier() ^ IER::MSI)
234 }
235
236 pub fn enable_modem_status_interrupt(&self) {
238 self.set_ier(self.ier() | IER::MSI)
239 }
240
241 pub fn disable_modem_status_interrupt(&self) {
243 self.set_ier(self.ier() & !IER::MSI)
244 }
245
246 pub fn is_receiver_line_status_interrupt_enabled(&self) -> bool {
248 self.ier().contains(IER::RLSI)
249 }
250
251 pub fn toggle_receiver_line_status_interrupt(&self) {
253 self.set_ier(self.ier() ^ IER::RLSI)
254 }
255
256 pub fn enable_receiver_line_status_interrupt(&self) {
258 self.set_ier(self.ier() | IER::RLSI)
259 }
260
261 pub fn disable_receiver_line_status_interrupt(&self) {
263 self.set_ier(self.ier() & !IER::RLSI)
264 }
265
266 pub fn is_transmitter_holding_register_empty_interrupt_enabled(&self) -> bool {
268 self.ier().contains(IER::THREI)
269 }
270
271 pub fn toggle_transmitter_holding_register_empty_interrupt(&self) {
273 self.set_ier(self.ier() ^ IER::THREI)
274 }
275
276 pub fn enable_transmitter_holding_register_empty_interrupt(&self) {
278 self.set_ier(self.ier() | IER::THREI)
279 }
280
281 pub fn disable_transmitter_holding_register_empty_interrupt(&self) {
283 self.set_ier(self.ier() & !IER::THREI)
284 }
285
286 pub fn is_received_data_available_interrupt_enabled(&self) -> bool {
288 self.ier().contains(IER::RDAI)
289 }
290
291 pub fn toggle_received_data_available_interrupt(&self) {
293 self.set_ier(self.ier() ^ IER::RDAI)
294 }
295
296 pub fn enable_received_data_available_interrupt(&self) {
298 self.set_ier(self.ier() | IER::RDAI)
299 }
300
301 pub fn disable_received_data_available_interrupt(&self) {
303 self.set_ier(self.ier() & !IER::RDAI)
304 }
305
306 #[inline]
308 pub fn read_iir(&self) -> u32 {
309 self.reg.rw[2].read()
310 }
311
312 pub fn is_fifo_enabled(&self) -> bool {
314 self.reg.rw[2].read() & 0b1100_0000 != 0
315 }
316
317 pub fn read_interrupt_type(&self) -> Option<InterruptType> {
319 let irq = self.reg.rw[2].read() & 0b0000_1111;
320 if irq & 1 != 0 {
321 None
322 } else {
323 match irq {
324 0b0000 => Some(InterruptType::ModemStatus),
325 0b0010 => Some(InterruptType::TransmitterHoldingRegisterEmpty),
326 0b0100 => Some(InterruptType::ReceivedDataAvailable),
327 0b0110 => Some(InterruptType::ReceiverLineStatus),
328 0b1100 => Some(InterruptType::Timeout),
329 0b1000 | 0b1010 | 0b1110 => Some(InterruptType::Reserved),
330 _ => panic!("Can't reached"),
331 }
332 }
333 }
334
335 pub unsafe fn is_interrupt_pending(&self) -> bool {
341 self.reg.rw[2].read() & 1 == 0
342 }
343
344 #[inline]
351 pub unsafe fn read_fcr(&self) -> u32 {
352 self.reg.rw[2].read()
353 }
354
355 #[inline]
357 pub fn write_fcr(&self, value: u32) {
358 unsafe { self.reg.rw[2].write(value) }
359 }
360
361 #[inline]
365 pub fn read_lcr(&self) -> u32 {
366 self.reg.rw[3].read()
367 }
368
369 #[inline]
373 pub fn write_lcr(&self, value: u32) {
374 unsafe { self.reg.rw[3].write(value) }
375 }
376
377 pub fn is_divisor_latch_accessible(&self) -> bool {
379 self.reg.rw[3].read() & 0b1000_0000 != 0
380 }
381
382 pub fn toggle_divisor_latch_accessible(&self) {
384 unsafe { self.reg.rw[3].modify(|v| v ^ 0b1000_0000) }
385 }
386
387 #[inline]
389 pub fn enable_divisor_latch_accessible(&self) {
390 unsafe { self.reg.rw[3].modify(|v| v | 0b1000_0000) }
391 }
392
393 #[inline]
395 pub fn disable_divisor_latch_accessible(&self) {
396 unsafe { self.reg.rw[3].modify(|v| v & !0b1000_0000) }
397 }
398
399 pub fn get_parity(&self) -> Parity {
401 match self.reg.rw[3].read() & 0b0011_1000 {
402 0b0000_0000 => Parity::No,
403 0b0000_1000 => Parity::Odd,
404 0b0001_1000 => Parity::Even,
405 0b0010_1000 => Parity::Mark,
406 0b0011_1000 => Parity::Space,
407 _ => panic!("Invalid Parity! Please check your uart"),
408 }
409 }
410
411 pub fn set_parity(&self, parity: Parity) {
413 match parity {
414 Parity::No => unsafe { self.reg.rw[3].modify(|v| (v & 0b1100_0111)) },
415 Parity::Odd => unsafe { self.reg.rw[3].modify(|v| (v & 0b1100_0111) | 0b0000_1000) },
416 Parity::Even => unsafe { self.reg.rw[3].modify(|v| (v & 0b1100_0111) | 0b0001_1000) },
417 Parity::Mark => unsafe { self.reg.rw[3].modify(|v| (v & 0b1100_0111) | 0b0010_1000) },
418 Parity::Space => unsafe { self.reg.rw[3].modify(|v| v | 0b0011_1000) },
419 }
420 }
421
422 pub fn get_stop_bit(&self) -> u32 {
426 ((self.reg.rw[3].read() & 0b100) >> 2) + 1
427 }
428
429 pub fn set_stop_bit(&self, stop_bit: u32) {
431 match stop_bit {
432 1 => unsafe { self.reg.rw[3].modify(|v| v & 0b1111_1011) },
433 2 => unsafe { self.reg.rw[3].modify(|v| v | 0b0000_0100) },
434 _ => panic!("Invalid stop bit"),
435 }
436 }
437
438 pub fn get_word_length(&self) -> u32 {
440 (self.reg.rw[3].read() & 0b11) + 5
441 }
442
443 pub fn set_word_length(&self, length: u32) {
445 if (5..=8).contains(&length) {
446 unsafe { self.reg.rw[3].modify(|v| v | (length - 5)) }
447 } else {
448 panic!("Invalid word length")
449 }
450 }
451
452 #[inline]
456 pub fn read_mcr(&self) -> u32 {
457 self.reg.rw[4].read()
458 }
459
460 #[inline]
464 pub fn write_mcr(&self, value: u32) {
465 unsafe { self.reg.rw[4].write(value) }
466 }
467
468 #[inline]
470 pub fn read_lsr(&self) -> u32 {
471 self.reg.ro[0].read()
472 }
473
474 #[inline]
476 pub fn lsr(&self) -> LSR {
477 LSR::from_bits_truncate(self.read_lsr() as u8)
478 }
479
480 pub fn is_received_fifo_error(&self) -> bool {
482 self.lsr().contains(LSR::RFE)
483 }
484
485 pub fn is_data_holding_registers_empty(&self) -> bool {
487 self.lsr().contains(LSR::DHRE)
488 }
489
490 pub fn is_transmitter_holding_register_empty(&self) -> bool {
492 self.lsr().contains(LSR::THRE)
493 }
494
495 pub fn is_break_interrupt(&self) -> bool {
496 self.lsr().contains(LSR::BI)
497 }
498
499 pub fn is_framing_error(&self) -> bool {
500 self.lsr().contains(LSR::FE)
501 }
502
503 pub fn is_parity_error(&self) -> bool {
504 self.lsr().contains(LSR::PE)
505 }
506
507 pub fn is_overrun_error(&self) -> bool {
508 self.lsr().contains(LSR::OE)
509 }
510
511 pub fn is_data_ready(&self) -> bool {
512 self.lsr().contains(LSR::DR)
513 }
514
515 #[inline]
517 pub fn read_msr(&self) -> u32 {
518 self.reg.ro[1].read()
519 }
520
521 #[inline]
523 pub fn msr(&self) -> MSR {
524 MSR::from_bits_truncate(self.read_msr() as u8)
525 }
526
527 pub fn is_carrier_detect(&self) -> bool {
528 self.msr().contains(MSR::CD)
529 }
530
531 pub fn is_ring_indicator(&self) -> bool {
532 self.msr().contains(MSR::RI)
533 }
534
535 pub fn is_data_set_ready(&self) -> bool {
536 self.msr().contains(MSR::DSR)
537 }
538
539 pub fn is_clear_to_send(&self) -> bool {
540 self.msr().contains(MSR::CTS)
541 }
542
543 pub fn is_delta_data_carrier_detect(&self) -> bool {
544 self.msr().contains(MSR::DDCD)
545 }
546
547 pub fn is_trailing_edge_ring_indicator(&self) -> bool {
548 self.msr().contains(MSR::TERI)
549 }
550
551 pub fn is_delta_data_set_ready(&self) -> bool {
552 self.msr().contains(MSR::DDSR)
553 }
554
555 pub fn is_delta_clear_to_send(&self) -> bool {
556 self.msr().contains(MSR::DCTS)
557 }
558
559 #[inline]
560 pub fn read_sr(&self) -> u32 {
561 self.reg.scratch.read()
562 }
563
564 #[inline]
565 pub fn write_sr(&self, value: u32) {
566 unsafe { self.reg.scratch.write(value) }
567 }
568}
569
570#[cfg(feature = "fmt")]
574impl<'a> fmt::Write for MmioUartAxi16550<'a> {
575 fn write_str(&mut self, s: &str) -> fmt::Result {
576 for c in s.as_bytes() {
577 self.write_thr((*c) as u32);
578 }
579 Ok(())
580 }
581}