1#![no_std]
5#![doc = include_str!("../README.md")]
6#![deny(clippy::undocumented_unsafe_blocks)]
7#![deny(unsafe_op_in_unsafe_fn)]
8
9#[cfg(feature = "embedded-hal-nb")]
40mod embedded_hal_nb;
41#[cfg(feature = "embedded-io")]
42mod embedded_io;
43
44use bitflags::bitflags;
45use core::fmt;
46pub use safe_mmio::UniqueMmioPointer;
47use safe_mmio::{
48 field, field_shared,
49 fields::{ReadPure, ReadPureWrite, ReadWrite, WriteOnly},
50};
51use thiserror::Error;
52use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
53
54#[repr(transparent)]
58#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
59struct DataRegister(u32);
60
61#[repr(transparent)]
63#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
64struct ReceiveStatusRegister(u32);
65
66#[repr(transparent)]
68#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
69struct FlagsRegister(u32);
70
71#[repr(transparent)]
73#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
74struct LineControlRegister(u32);
75
76#[repr(transparent)]
78#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
79struct ControlRegister(u32);
80
81#[repr(transparent)]
84#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
85pub struct Interrupts(u32);
86
87bitflags! {
88 impl DataRegister: u32 {
89 const OE = 1 << 11;
91 const BE = 1 << 10;
93 const PE = 1 << 9;
95 const FE = 1 << 8;
97 }
98
99 impl ReceiveStatusRegister: u32 {
100 const OE = 1 << 3;
102 const BE = 1 << 2;
104 const PE = 1 << 1;
106 const FE = 1 << 0;
108 }
109
110 impl FlagsRegister: u32 {
111 const RI = 1 << 8;
113 const TXFE = 1 << 7;
115 const RXFF = 1 << 6;
117 const TXFF = 1 << 5;
119 const RXFE = 1 << 4;
121 const BUSY = 1 << 3;
123 const DCD = 1 << 2;
125 const DSR = 1 << 1;
127 const CTS = 1 << 0;
129 }
130
131 impl LineControlRegister: u32 {
132 const SPS = 1 << 7;
134 const WLEN_5BITS = 0b00 << 5;
136 const WLEN_6BITS = 0b01 << 5;
137 const WLEN_7BITS = 0b10 << 5;
138 const WLEN_8BITS = 0b11 << 5;
139 const FEN = 1 << 4;
141 const STP2 = 1 << 3;
143 const EPS = 1 << 2;
145 const PEN = 1 << 1;
147 const BRK = 1 << 0;
149 }
150
151 impl ControlRegister: u32 {
152 const CTSEn = 1 << 15;
154 const RTSEn = 1 << 14;
156 const Out2 = 1 << 13;
158 const Out1 = 1 << 12;
160 const RTS = 1 << 11;
162 const DTR = 1 << 10;
164 const RXE = 1 << 9;
166 const TXE = 1 << 8;
168 const LBE = 1 << 7;
170 const SIRLP = 1 << 2;
172 const SIREN = 1 << 1;
174 const UARTEN = 1 << 0;
176 }
177
178 impl Interrupts: u32 {
179 const OEI = 1 << 10;
181 const BEI = 1 << 9;
183 const PEI = 1 << 8;
185 const FEI = 1 << 7;
187 const RTI = 1 << 6;
189 const TXI = 1 << 5;
191 const RXI = 1 << 4;
193 const DSRMI = 1 << 3;
195 const DCDMI = 1 << 2;
197 const CTSMI = 1 << 1;
199 const RIMI = 1 << 0;
201 }
202}
203
204#[derive(Clone, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
206#[repr(C, align(4))]
207pub struct PL011Registers {
208 uartdr: ReadWrite<u32>,
210 uartrsr_ecr: ReadPureWrite<u32>,
212 reserved_08: [u32; 4],
214 uartfr: ReadPure<FlagsRegister>,
216 reserved_1c: u32,
218 uartilpr: ReadPureWrite<u32>,
220 uartibrd: ReadPureWrite<u32>,
222 uartfbrd: ReadPureWrite<u32>,
224 uartlcr_h: ReadPureWrite<LineControlRegister>,
226 uartcr: ReadPureWrite<ControlRegister>,
228 uartifls: ReadPureWrite<u32>,
230 uartimsc: ReadPureWrite<Interrupts>,
232 uartris: ReadPure<Interrupts>,
234 uartmis: ReadPure<Interrupts>,
236 uarticr: WriteOnly<Interrupts>,
238 uartdmacr: ReadPureWrite<u32>,
240 reserved_4c: [u32; 997],
242 uartperiphid0: ReadPure<u32>,
244 uartperiphid1: ReadPure<u32>,
246 uartperiphid2: ReadPure<u32>,
248 uartperiphid3: ReadPure<u32>,
250 uartpcellid0: ReadPure<u32>,
252 uartpcellid1: ReadPure<u32>,
254 uartpcellid2: ReadPure<u32>,
256 uartpcellid3: ReadPure<u32>,
258}
259
260#[derive(Clone, Copy, Debug, Eq, PartialEq)]
264pub enum DataBits {
265 Bits5,
266 Bits6,
267 Bits7,
268 Bits8,
269}
270
271#[derive(Clone, Copy, Debug, Eq, PartialEq)]
273pub enum Parity {
274 None,
275 Even,
276 Odd,
277 One,
278 Zero,
279}
280
281#[derive(Clone, Copy, Debug, Eq, PartialEq)]
283pub enum StopBits {
284 One,
285 Two,
286}
287
288#[derive(Clone, Copy, Debug, Eq, PartialEq)]
290pub struct LineConfig {
291 pub data_bits: DataBits,
292 pub parity: Parity,
293 pub stop_bits: StopBits,
294}
295
296#[derive(Clone, Copy, Debug, Eq, PartialEq)]
298pub enum FifoLevel {
299 Bytes4 = 0b000,
300 Bytes8 = 0b001,
301 Bytes16 = 0b010,
302 Bytes24 = 0b011,
303 Bytes28 = 0b100,
304}
305
306#[derive(Clone, Copy, Debug, Eq, PartialEq)]
308pub struct Identification {
309 pub part_number: u16,
310 pub designer: u8,
311 pub revision_number: u8,
312 pub configuration: u8,
313}
314
315impl Identification {
316 const PART_NUMBER: u16 = 0x11;
317 const DESIGNER_ARM: u8 = b'A';
318 const REVISION_MAX: u8 = 0x03;
319 const CONFIGURATION: u8 = 0x00;
320
321 pub fn is_valid(&self) -> bool {
323 self.part_number == Self::PART_NUMBER
324 && self.designer == Self::DESIGNER_ARM
325 && self.revision_number <= Self::REVISION_MAX
326 && self.configuration == Self::CONFIGURATION
327 }
328}
329
330#[derive(Clone, Copy, Debug, Error, Eq, PartialEq)]
332pub enum Error {
333 #[error("Invalid parameter")]
334 InvalidParameter,
335 #[error("Overrun")]
336 Overrun,
337 #[error("Break")]
338 Break,
339 #[error("Parity")]
340 Parity,
341 #[error("Framing")]
342 Framing,
343}
344
345pub struct Uart<'a> {
347 regs: UniqueMmioPointer<'a, PL011Registers>,
348}
349
350impl<'a> Uart<'a> {
351 pub fn new(regs: UniqueMmioPointer<'a, PL011Registers>) -> Self {
353 Self { regs }
354 }
355
356 pub fn enable(&mut self, config: LineConfig, baud_rate: u32, sysclk: u32) -> Result<(), Error> {
358 let (uartibrd, uartfbrd) = Self::calculate_baud_rate_divisor(baud_rate, sysclk)?;
360
361 let line_control = match config.data_bits {
363 DataBits::Bits5 => LineControlRegister::WLEN_5BITS,
364 DataBits::Bits6 => LineControlRegister::WLEN_6BITS,
365 DataBits::Bits7 => LineControlRegister::WLEN_7BITS,
366 DataBits::Bits8 => LineControlRegister::WLEN_8BITS,
367 } | match config.parity {
368 Parity::None => LineControlRegister::empty(),
369 Parity::Even => LineControlRegister::PEN | LineControlRegister::EPS,
370 Parity::Odd => LineControlRegister::PEN,
371 Parity::One => LineControlRegister::PEN | LineControlRegister::SPS,
372 Parity::Zero => {
373 LineControlRegister::PEN | LineControlRegister::EPS | LineControlRegister::SPS
374 }
375 } | match config.stop_bits {
376 StopBits::One => LineControlRegister::empty(),
377 StopBits::Two => LineControlRegister::STP2,
378 } | LineControlRegister::FEN;
379
380 field!(self.regs, uartrsr_ecr).write(0);
381 field!(self.regs, uartcr).write(ControlRegister::empty());
382
383 field!(self.regs, uartibrd).write(uartibrd);
384 field!(self.regs, uartfbrd).write(uartfbrd);
385 field!(self.regs, uartlcr_h).write(line_control);
386
387 field!(self.regs, uartcr)
388 .write(ControlRegister::RXE | ControlRegister::TXE | ControlRegister::UARTEN);
389
390 Ok(())
391 }
392
393 pub fn disable(&mut self) {
395 field!(self.regs, uartcr).write(ControlRegister::empty());
396 }
397
398 pub fn is_rx_fifo_empty(&self) -> bool {
400 self.flags().contains(FlagsRegister::RXFE)
401 }
402
403 pub fn is_rx_fifo_full(&self) -> bool {
405 self.flags().contains(FlagsRegister::RXFF)
406 }
407
408 pub fn is_tx_fifo_empty(&self) -> bool {
410 self.flags().contains(FlagsRegister::TXFE)
411 }
412
413 pub fn is_tx_fifo_full(&self) -> bool {
415 self.flags().contains(FlagsRegister::TXFF)
416 }
417
418 pub fn is_busy(&self) -> bool {
420 self.flags().contains(FlagsRegister::BUSY)
421 }
422
423 fn flags(&self) -> FlagsRegister {
425 field_shared!(self.regs, uartfr).read()
426 }
427
428 pub fn read_word(&mut self) -> Result<Option<u8>, Error> {
432 if self.is_rx_fifo_empty() {
433 return Ok(None);
434 }
435
436 let dr = field!(self.regs, uartdr).read();
437
438 let flags = DataRegister::from_bits_truncate(dr);
439
440 if flags.contains(DataRegister::OE) {
441 return Err(Error::Overrun);
442 } else if flags.contains(DataRegister::BE) {
443 return Err(Error::Break);
444 } else if flags.contains(DataRegister::PE) {
445 return Err(Error::Parity);
446 } else if flags.contains(DataRegister::FE) {
447 return Err(Error::Framing);
448 }
449
450 Ok(Some(dr as u8))
451 }
452
453 pub fn write_word(&mut self, word: u8) {
455 field!(self.regs, uartdr).write(word as u32);
456 }
457
458 pub fn read_identification(&self) -> Identification {
460 let id: [u32; 4] = {
463 [
464 field_shared!(self.regs, uartperiphid0).read(),
465 field_shared!(self.regs, uartperiphid1).read(),
466 field_shared!(self.regs, uartperiphid2).read(),
467 field_shared!(self.regs, uartperiphid3).read(),
468 ]
469 };
470
471 Identification {
472 part_number: (id[0] & 0xff) as u16 | ((id[1] & 0x0f) << 8) as u16,
473 designer: ((id[1] & 0xf0) >> 4) as u8 | ((id[2] & 0x0f) << 4) as u8,
474 revision_number: ((id[2] & 0xf0) >> 4) as u8,
475 configuration: (id[3] & 0xff) as u8,
476 }
477 }
478
479 fn calculate_baud_rate_divisor(baud_rate: u32, sysclk: u32) -> Result<(u32, u32), Error> {
480 let baud_div = sysclk
485 .checked_mul(8)
486 .and_then(|clk| clk.checked_div(baud_rate))
487 .ok_or(Error::InvalidParameter)?;
488 let baud_div_bits = baud_div
489 .checked_add(1)
490 .map(|div| div >> 1)
491 .ok_or(Error::InvalidParameter)?;
492
493 let ibrd = baud_div_bits >> 6;
494 let fbrd = baud_div_bits & 0x3F;
495
496 if ibrd == 0 || (ibrd == 0xffff && fbrd != 0) || ibrd > 0xffff {
497 return Err(Error::InvalidParameter);
498 }
499
500 Ok((ibrd, fbrd))
501 }
502
503 pub fn set_interrupt_fifo_levels(&mut self, rx_level: FifoLevel, tx_level: FifoLevel) {
506 let fifo_levels = ((rx_level as u32) << 3) | tx_level as u32;
507
508 field!(self.regs, uartifls).write(fifo_levels);
509 }
510
511 pub fn raw_interrupt_status(&self) -> Interrupts {
513 field_shared!(self.regs, uartris).read()
514 }
515
516 pub fn masked_interrupt_status(&self) -> Interrupts {
518 field_shared!(self.regs, uartmis).read()
519 }
520
521 pub fn interrupt_masks(&self) -> Interrupts {
523 field_shared!(self.regs, uartimsc).read()
524 }
525
526 pub fn set_interrupt_masks(&mut self, masks: Interrupts) {
528 field!(self.regs, uartimsc).write(masks)
529 }
530
531 pub fn clear_interrupts(&mut self, interrupts: Interrupts) {
533 field!(self.regs, uarticr).write(interrupts)
534 }
535}
536
537unsafe impl Sync for Uart<'_> {}
540
541impl fmt::Write for Uart<'_> {
542 fn write_str(&mut self, s: &str) -> fmt::Result {
543 for byte in s.as_bytes() {
544 while self.is_tx_fifo_full() {}
546 self.write_word(*byte);
547 }
548 Ok(())
549 }
550}
551
552#[cfg(test)]
553mod tests {
554 use super::*;
555 use zerocopy::transmute_mut;
556
557 pub struct FakePL011Registers {
558 regs: [u32; 1024],
559 }
560
561 impl FakePL011Registers {
562 pub fn new() -> Self {
563 Self { regs: [0u32; 1024] }
564 }
565
566 pub fn clear(&mut self) {
567 self.regs.fill(0);
568 }
569
570 pub fn reg_write(&mut self, offset: usize, value: u32) {
571 self.regs[offset / 4] = value;
572 }
573
574 pub fn reg_read(&self, offset: usize) -> u32 {
575 self.regs[offset / 4]
576 }
577
578 fn get(&mut self) -> UniqueMmioPointer<'_, PL011Registers> {
579 UniqueMmioPointer::from(transmute_mut!(&mut self.regs))
580 }
581
582 pub fn uart_for_test(&mut self) -> Uart<'_> {
583 Uart::new(self.get())
584 }
585 }
586
587 #[test]
588 fn regs_size() {
589 assert_eq!(core::mem::size_of::<PL011Registers>(), 0x1000);
590 }
591
592 #[test]
593 fn enable_230400_8n1() {
594 let mut regs = FakePL011Registers::new();
595 let mut uart = regs.uart_for_test();
596 let config = LineConfig {
597 data_bits: DataBits::Bits8,
598 parity: Parity::None,
599 stop_bits: StopBits::One,
600 };
601
602 assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
604
605 assert_eq!(0x00, regs.reg_read(0x004)); assert_eq!(1, regs.reg_read(0x024)); assert_eq!(5, regs.reg_read(0x028)); assert_eq!(0b01110000, regs.reg_read(0x02c)); assert_eq!(0x0301, regs.reg_read(0x030)); }
611
612 #[test]
613 fn enable_example_baudrates() {
614 let mut regs = FakePL011Registers::new();
616
617 {
618 let mut uart = regs.uart_for_test();
619 let config = LineConfig {
620 data_bits: DataBits::Bits8,
621 parity: Parity::None,
622 stop_bits: StopBits::One,
623 };
624
625 assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
626 assert_eq!(0x1, regs.reg_read(0x024)); assert_eq!(0x5, regs.reg_read(0x028)); }
629
630 regs.clear();
631
632 {
633 let mut uart = regs.uart_for_test();
634 let config = LineConfig {
635 data_bits: DataBits::Bits8,
636 parity: Parity::None,
637 stop_bits: StopBits::One,
638 };
639
640 assert_eq!(Ok(()), uart.enable(config, 115200, 4_000_000));
641 assert_eq!(0x2, regs.reg_read(0x024)); assert_eq!(0xb, regs.reg_read(0x028)); }
644
645 regs.clear();
646
647 {
648 let mut uart = regs.uart_for_test();
649 let config = LineConfig {
650 data_bits: DataBits::Bits8,
651 parity: Parity::None,
652 stop_bits: StopBits::One,
653 };
654
655 assert_eq!(Ok(()), uart.enable(config, 76800, 4_000_000));
656 assert_eq!(0x3, regs.reg_read(0x024)); assert_eq!(0x10, regs.reg_read(0x028)); }
659
660 regs.clear();
661
662 {
663 let mut uart = regs.uart_for_test();
664 let config = LineConfig {
665 data_bits: DataBits::Bits8,
666 parity: Parity::None,
667 stop_bits: StopBits::One,
668 };
669
670 assert_eq!(Ok(()), uart.enable(config, 38400, 4_000_000));
671 assert_eq!(0x6, regs.reg_read(0x024)); assert_eq!(0x21, regs.reg_read(0x028)); }
674
675 regs.clear();
676
677 {
678 let mut uart = regs.uart_for_test();
679 let config = LineConfig {
680 data_bits: DataBits::Bits8,
681 parity: Parity::None,
682 stop_bits: StopBits::One,
683 };
684
685 assert_eq!(Ok(()), uart.enable(config, 14400, 4_000_000));
686 assert_eq!(0x11, regs.reg_read(0x024)); assert_eq!(0x17, regs.reg_read(0x028)); }
689
690 regs.clear();
691
692 {
693 let mut uart = regs.uart_for_test();
694 let config = LineConfig {
695 data_bits: DataBits::Bits8,
696 parity: Parity::None,
697 stop_bits: StopBits::One,
698 };
699
700 assert_eq!(Ok(()), uart.enable(config, 2400, 4_000_000));
701 assert_eq!(0x68, regs.reg_read(0x024)); assert_eq!(0xb, regs.reg_read(0x028)); }
704
705 regs.clear();
706
707 {
708 let mut uart = regs.uart_for_test();
709 let config = LineConfig {
710 data_bits: DataBits::Bits8,
711 parity: Parity::None,
712 stop_bits: StopBits::One,
713 };
714
715 assert_eq!(Ok(()), uart.enable(config, 110, 4_000_000));
716 assert_eq!(0x8e0, regs.reg_read(0x024)); assert_eq!(0x2f, regs.reg_read(0x028)); }
719 }
720
721 #[test]
722 fn enable_invalid_baudrates() {
723 let mut regs = FakePL011Registers::new();
724 let mut uart = regs.uart_for_test();
725
726 {
727 let config = LineConfig {
728 data_bits: DataBits::Bits8,
729 parity: Parity::None,
730 stop_bits: StopBits::One,
731 };
732
733 assert_eq!(
734 Err(Error::InvalidParameter),
735 uart.enable(config, 0, 4_000_000)
736 );
737 }
738
739 {
740 let config = LineConfig {
741 data_bits: DataBits::Bits8,
742 parity: Parity::None,
743 stop_bits: StopBits::One,
744 };
745 assert_eq!(
746 Err(Error::InvalidParameter),
747 uart.enable(config, 1, 1048561)
748 );
749 }
750
751 {
752 let config = LineConfig {
753 data_bits: DataBits::Bits8,
754 parity: Parity::None,
755 stop_bits: StopBits::One,
756 };
757 assert_eq!(
758 Err(Error::InvalidParameter),
759 uart.enable(config, 1, 100_000_000)
760 );
761 }
762
763 {
764 let config = LineConfig {
765 data_bits: DataBits::Bits8,
766 parity: Parity::None,
767 stop_bits: StopBits::One,
768 };
769 assert_eq!(Err(Error::InvalidParameter), uart.enable(config, 1, 1));
770 }
771 }
772
773 #[test]
774 fn enable_lineconfigs() {
775 let mut regs = FakePL011Registers::new();
776 {
777 let mut uart = regs.uart_for_test();
779 let config = LineConfig {
780 data_bits: DataBits::Bits7,
781 parity: Parity::Even,
782 stop_bits: StopBits::Two,
783 };
784
785 assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
786 assert_eq!(0b01011110, regs.reg_read(0x02c)); }
788
789 regs.clear();
790
791 {
792 let mut regs = FakePL011Registers::new();
794 let mut uart = regs.uart_for_test();
795 let config = LineConfig {
796 data_bits: DataBits::Bits6,
797 parity: Parity::Odd,
798 stop_bits: StopBits::One,
799 };
800
801 assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
802 assert_eq!(0b00110010, regs.reg_read(0x02c)); }
804
805 regs.clear();
806
807 {
808 let mut regs = FakePL011Registers::new();
810 let mut uart = regs.uart_for_test();
811 let config = LineConfig {
812 data_bits: DataBits::Bits5,
813 parity: Parity::One,
814 stop_bits: StopBits::One,
815 };
816
817 assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
818 assert_eq!(0b10010010, regs.reg_read(0x02c)); }
820
821 {
822 let mut regs = FakePL011Registers::new();
824 let mut uart = regs.uart_for_test();
825 let config = LineConfig {
826 data_bits: DataBits::Bits5,
827 parity: Parity::Zero,
828 stop_bits: StopBits::Two,
829 };
830
831 assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
832 assert_eq!(0b10011110, regs.reg_read(0x02c)); }
834 }
835
836 #[test]
837 fn disable() {
838 let mut regs = FakePL011Registers::new();
839 let mut uart = regs.uart_for_test();
840 let config = LineConfig {
841 data_bits: DataBits::Bits8,
842 parity: Parity::None,
843 stop_bits: StopBits::One,
844 };
845
846 assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
847 uart.disable();
848 assert_eq!(0, regs.reg_read(0x030)); }
850
851 #[test]
852 fn rx_fifo_empty() {
853 let mut regs = FakePL011Registers::new();
854 {
855 let uart = regs.uart_for_test();
856 assert!(!uart.is_rx_fifo_empty());
857 }
858
859 {
860 regs.reg_write(0x018, 1 << 4);
861 let uart = regs.uart_for_test();
862 assert!(uart.is_rx_fifo_empty());
863 }
864 }
865
866 #[test]
867 fn rx_fifo_full() {
868 let mut regs = FakePL011Registers::new();
869 {
870 let uart = regs.uart_for_test();
871 assert!(!uart.is_rx_fifo_full());
872 }
873
874 {
875 regs.reg_write(0x018, 1 << 6);
876 let uart = regs.uart_for_test();
877 assert!(uart.is_rx_fifo_full());
878 }
879 }
880
881 #[test]
882 fn tx_fifo_empty() {
883 let mut regs = FakePL011Registers::new();
884 {
885 let uart = regs.uart_for_test();
886 assert!(!uart.is_tx_fifo_empty());
887 }
888
889 {
890 regs.reg_write(0x018, 1 << 7);
891 let uart = regs.uart_for_test();
892 assert!(uart.is_tx_fifo_empty());
893 }
894 }
895
896 #[test]
897 fn tx_fifo_full() {
898 let mut regs = FakePL011Registers::new();
899 {
900 let uart = regs.uart_for_test();
901 assert!(!uart.is_tx_fifo_full());
902 }
903
904 {
905 regs.reg_write(0x018, 1 << 5);
906 let uart = regs.uart_for_test();
907 assert!(uart.is_tx_fifo_full());
908 }
909 }
910
911 #[test]
912 fn busy() {
913 let mut regs = FakePL011Registers::new();
914 {
915 let uart = regs.uart_for_test();
916 assert!(!uart.is_busy());
917 }
918
919 {
920 regs.reg_write(0x018, 1 << 3);
921 let uart = regs.uart_for_test();
922 assert!(uart.is_busy());
923 }
924 }
925
926 #[test]
927 fn read_word() {
928 let mut regs = FakePL011Registers::new();
929
930 {
931 regs.reg_write(0x000, 1 << 11);
932
933 let mut uart = regs.uart_for_test();
934 assert_eq!(Err(Error::Overrun), uart.read_word());
935 }
936
937 {
938 regs.reg_write(0x000, 1 << 10);
939
940 let mut uart = regs.uart_for_test();
941 assert_eq!(Err(Error::Break), uart.read_word());
942 }
943
944 {
945 regs.reg_write(0x000, 1 << 9);
946
947 let mut uart = regs.uart_for_test();
948 assert_eq!(Err(Error::Parity), uart.read_word());
949 }
950
951 {
952 regs.reg_write(0x000, 1 << 8);
953
954 let mut uart = regs.uart_for_test();
955 assert_eq!(Err(Error::Framing), uart.read_word());
956 }
957
958 {
959 regs.reg_write(0x000, 0x41);
960
961 let mut uart = regs.uart_for_test();
962 assert_eq!(Ok(Some(0x41)), uart.read_word());
963 }
964
965 {
966 regs.reg_write(0x018, 0x10);
967
968 let mut uart = regs.uart_for_test();
969 assert_eq!(Ok(None), uart.read_word());
970 }
971 }
972
973 #[test]
974 fn write_word() {
975 let mut regs = FakePL011Registers::new();
976
977 let mut uart = regs.uart_for_test();
978 uart.write_word(0x41);
979
980 assert_eq!(0x41, regs.reg_read(0x000));
981 }
982
983 #[test]
984 fn read_identification() {
985 let mut regs = FakePL011Registers::new();
986
987 regs.reg_write(0xfe0, 0x11);
988 regs.reg_write(0xfe4, 0x10);
989 regs.reg_write(0xfe8, 0x34);
990 regs.reg_write(0xfec, 0x00);
991
992 let uart = regs.uart_for_test();
993 let identification = uart.read_identification();
994 assert_eq!(0x0011, identification.part_number);
995 assert_eq!(0x41, identification.designer);
996 assert_eq!(0x03, identification.revision_number);
997 assert_eq!(0x00, identification.configuration);
998 assert!(identification.is_valid());
999 }
1000
1001 #[test]
1002 fn fifo_level() {
1003 let mut regs = FakePL011Registers::new();
1004
1005 {
1006 let mut uart = regs.uart_for_test();
1007 uart.set_interrupt_fifo_levels(FifoLevel::Bytes4, FifoLevel::Bytes8);
1008 }
1009 assert_eq!(regs.reg_read(0x34), 0x01);
1010
1011 {
1012 let mut uart = regs.uart_for_test();
1013 uart.set_interrupt_fifo_levels(FifoLevel::Bytes8, FifoLevel::Bytes16);
1014 }
1015 assert_eq!(regs.reg_read(0x34), 0x0a);
1016
1017 {
1018 let mut uart = regs.uart_for_test();
1019 uart.set_interrupt_fifo_levels(FifoLevel::Bytes16, FifoLevel::Bytes24);
1020 }
1021 assert_eq!(regs.reg_read(0x34), 0x13);
1022
1023 {
1024 let mut uart = regs.uart_for_test();
1025 uart.set_interrupt_fifo_levels(FifoLevel::Bytes24, FifoLevel::Bytes28);
1026 }
1027 assert_eq!(regs.reg_read(0x34), 0x1c);
1028
1029 {
1030 let mut uart = regs.uart_for_test();
1031 uart.set_interrupt_fifo_levels(FifoLevel::Bytes28, FifoLevel::Bytes4);
1032 }
1033 assert_eq!(regs.reg_read(0x34), 0x20);
1034 }
1035
1036 #[test]
1037 fn interrupt_status() {
1038 let mut regs = FakePL011Registers::new();
1039
1040 {
1041 let uart = regs.uart_for_test();
1042 assert_eq!(uart.raw_interrupt_status(), Interrupts::empty());
1043 assert_eq!(uart.masked_interrupt_status(), Interrupts::empty());
1044 }
1045
1046 {
1047 regs.reg_write(0x3c, 0b0000_0110_0000_1001);
1048 regs.reg_write(0x40, 0b0000_0100_0000_0001);
1049 let uart = regs.uart_for_test();
1050 assert_eq!(
1051 uart.raw_interrupt_status(),
1052 Interrupts::OEI | Interrupts::BEI | Interrupts::DSRMI | Interrupts::RIMI
1053 );
1054 assert_eq!(
1055 uart.masked_interrupt_status(),
1056 Interrupts::OEI | Interrupts::RIMI
1057 );
1058 }
1059 }
1060
1061 #[test]
1062 fn interrupt_mask() {
1063 let mut regs = FakePL011Registers::new();
1064
1065 {
1066 let mut uart = regs.uart_for_test();
1067 assert_eq!(uart.interrupt_masks(), Interrupts::empty());
1068
1069 uart.set_interrupt_masks(Interrupts::BEI | Interrupts::RTI);
1070 assert_eq!(uart.interrupt_masks(), Interrupts::BEI | Interrupts::RTI);
1071 }
1072
1073 assert_eq!(regs.reg_read(0x38), 0b0000_0010_0100_0000);
1074 }
1075
1076 #[test]
1077 fn interrupt_clear() {
1078 let mut regs = FakePL011Registers::new();
1079
1080 {
1081 let mut uart = regs.uart_for_test();
1082 uart.clear_interrupts(Interrupts::OEI | Interrupts::RIMI | Interrupts::RTI);
1083 }
1084
1085 assert_eq!(regs.reg_read(0x44), 0b0000_0100_0100_0001);
1086 }
1087
1088 #[test]
1089 fn core_write() {
1090 let mut regs = FakePL011Registers::new();
1091 let mut uart = regs.uart_for_test();
1092 assert_eq!(Ok(()), core::fmt::Write::write_str(&mut uart, "hello"));
1093 }
1094}