arm_pl011_uart/
lib.rs

1// SPDX-FileCopyrightText: Copyright The arm-pl011-uart Contributors.
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4#![no_std]
5#![doc = include_str!("../README.md")]
6#![deny(clippy::undocumented_unsafe_blocks)]
7#![deny(unsafe_op_in_unsafe_fn)]
8
9//! ## Example
10//!
11//! ```rust
12//! use arm_pl011_uart::{DataBits, LineConfig, Parity, PL011Registers, StopBits, Uart, UniqueMmioPointer};
13//! use core::{fmt::Write, ptr::NonNull};
14//! # use zerocopy::transmute_mut;
15//! # let mut fake_registers = [0u32; 1024];
16//! # let UART_ADDRESS : *mut PL011Registers = transmute_mut!(&mut fake_registers);
17//!
18//! // SAFETY: `UART_ADDRESS` is the base address of a PL011 UART register block. It remains valid for
19//! // the lifetime of the application and nothing else references this address range.
20//! let uart_pointer = unsafe { UniqueMmioPointer::new(NonNull::new(UART_ADDRESS).unwrap()) };
21//!
22//! // Create driver instance
23//! let mut uart = Uart::new(uart_pointer);
24//!
25//! // Configure and enable UART
26//! let line_config = LineConfig {
27//!     data_bits: DataBits::Bits8,
28//!     parity: Parity::None,
29//!     stop_bits: StopBits::One,
30//! };
31//! uart.enable(line_config, 115_200, 16_000_000);
32//!
33//! // Send and receive data
34//! uart.write_word(0x5a);
35//! uart.write_str("Hello Uart!");
36//! println!("{:?}", uart.read_word());
37//! ```
38
39#[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// Register descriptions
55
56/// Data Register
57#[repr(transparent)]
58#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
59struct DataRegister(u32);
60
61/// Receive Status Register/Error Clear Register, UARTRSR/UARTECR
62#[repr(transparent)]
63#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
64struct ReceiveStatusRegister(u32);
65
66/// Flag Register, UARTFR
67#[repr(transparent)]
68#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
69struct FlagsRegister(u32);
70
71/// Line Control Register, UARTLCR_H
72#[repr(transparent)]
73#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
74struct LineControlRegister(u32);
75
76/// Control Register, UARTCR
77#[repr(transparent)]
78#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
79struct ControlRegister(u32);
80
81/// Set of interrupts. This is used for the interrupt status registers (UARTRIS and UARTMIS),
82/// interrupt mask register (UARTIMSC) and and interrupt clear register (UARTICR).
83#[repr(transparent)]
84#[derive(Copy, Clone, Debug, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
85pub struct Interrupts(u32);
86
87bitflags! {
88    impl DataRegister: u32 {
89        /// Overrun error
90        const OE = 1 << 11;
91        /// Break error
92        const BE = 1 << 10;
93        /// Parity error
94        const PE = 1 << 9;
95        /// Framing error
96        const FE = 1 << 8;
97    }
98
99    impl ReceiveStatusRegister: u32 {
100        /// Overrun error
101        const OE = 1 << 3;
102        /// Break error
103        const BE = 1 << 2;
104        /// Parity error
105        const PE = 1 << 1;
106        /// Framing error
107        const FE = 1 << 0;
108    }
109
110    impl FlagsRegister: u32 {
111        /// Ring indicator
112        const RI = 1 << 8;
113        /// Transmit FIFO is empty
114        const TXFE = 1 << 7;
115        /// Receive FIFO is full
116        const RXFF = 1 << 6;
117        /// Transmit FIFO is full
118        const TXFF = 1 << 5;
119        /// Receive FIFO is empty
120        const RXFE = 1 << 4;
121        /// UART busy
122        const BUSY = 1 << 3;
123        /// Data carrier detect
124        const DCD = 1 << 2;
125        /// Data set ready
126        const DSR = 1 << 1;
127        /// Clear to send
128        const CTS = 1 << 0;
129    }
130
131    impl LineControlRegister: u32 {
132        /// Stick parity select.
133        const SPS = 1 << 7;
134        /// Word length
135        const WLEN_5BITS = 0b00 << 5;
136        const WLEN_6BITS = 0b01 << 5;
137        const WLEN_7BITS = 0b10 << 5;
138        const WLEN_8BITS = 0b11 << 5;
139        /// Enable FIFOs
140        const FEN = 1 << 4;
141        /// Two stop bits select
142        const STP2 = 1 << 3;
143        /// Even parity select
144        const EPS = 1 << 2;
145        /// Parity enable
146        const PEN = 1 << 1;
147        /// Send break
148        const BRK = 1 << 0;
149    }
150
151    impl ControlRegister: u32 {
152        /// CTS hardware flow control enable
153        const CTSEn = 1 << 15;
154        /// RTS hardware flow control enable
155        const RTSEn = 1 << 14;
156        /// This bit is the complement of the UART Out2 (nUARTOut2) modem status output
157        const Out2 = 1 << 13;
158        /// This bit is the complement of the UART Out1 (nUARTOut1) modem status output
159        const Out1 = 1 << 12;
160        /// Request to send
161        const RTS = 1 << 11;
162        /// Data transmit ready
163        const DTR = 1 << 10;
164        /// Receive enable
165        const RXE = 1 << 9;
166        /// Transmit enable
167        const TXE = 1 << 8;
168        /// Loopback enable
169        const LBE = 1 << 7;
170        /// SIR low-power IrDA mode
171        const SIRLP = 1 << 2;
172        /// SIR enable
173        const SIREN = 1 << 1;
174        /// UART enable
175        const UARTEN = 1 << 0;
176    }
177
178    impl Interrupts: u32 {
179        /// Overrun error interrupt.
180        const OEI = 1 << 10;
181        /// Break error interrupt.
182        const BEI = 1 << 9;
183        /// Parity error interrupt.
184        const PEI = 1 << 8;
185        /// Framing error interrupt.
186        const FEI = 1 << 7;
187        /// Receive timeout interrupt.
188        const RTI = 1 << 6;
189        /// Transmit interrupt.
190        const TXI = 1 << 5;
191        /// Receive interrupt.
192        const RXI = 1 << 4;
193        /// nUARTDSR modem interrupt.
194        const DSRMI = 1 << 3;
195        /// nUARTDCD modem interrupt.
196        const DCDMI = 1 << 2;
197        /// nUARTCTS modem interrupt.
198        const CTSMI = 1 << 1;
199        /// nUARTRI modem interrupt.
200        const RIMI = 1 << 0;
201    }
202}
203
204/// PL011 register map
205#[derive(Clone, Eq, FromBytes, Immutable, IntoBytes, KnownLayout, PartialEq)]
206#[repr(C, align(4))]
207pub struct PL011Registers {
208    /// 0x000: Data Register
209    uartdr: ReadWrite<u32>,
210    /// 0x004: Receive Status Register/Error Clear Register
211    uartrsr_ecr: ReadPureWrite<u32>,
212    /// 0x008 - 0x014
213    reserved_08: [u32; 4],
214    /// 0x018: Flag Register
215    uartfr: ReadPure<FlagsRegister>,
216    /// 0x01C
217    reserved_1c: u32,
218    /// 0x020: IrDA Low-Power Counter Register
219    uartilpr: ReadPureWrite<u32>,
220    /// 0x024: Integer Baud Rate Register
221    uartibrd: ReadPureWrite<u32>,
222    /// 0x028: Fractional Baud Rate Register
223    uartfbrd: ReadPureWrite<u32>,
224    /// 0x02C: Line Control Register
225    uartlcr_h: ReadPureWrite<LineControlRegister>,
226    /// 0x030: Control Register
227    uartcr: ReadPureWrite<ControlRegister>,
228    /// 0x034: Interrupt FIFO Level Select Register
229    uartifls: ReadPureWrite<u32>,
230    /// 0x038: Interrupt Mask Set/Clear Register
231    uartimsc: ReadPureWrite<Interrupts>,
232    /// 0x03C: Raw Interrupt Status Register
233    uartris: ReadPure<Interrupts>,
234    /// 0x040: Masked INterrupt Status Register
235    uartmis: ReadPure<Interrupts>,
236    /// 0x044: Interrupt Clear Register
237    uarticr: WriteOnly<Interrupts>,
238    /// 0x048: DMA control Register
239    uartdmacr: ReadPureWrite<u32>,
240    /// 0x04C - 0xFDC
241    reserved_4c: [u32; 997],
242    /// 0xFE0: UARTPeriphID0 Register
243    uartperiphid0: ReadPure<u32>,
244    /// 0xFE4: UARTPeriphID1 Register
245    uartperiphid1: ReadPure<u32>,
246    /// 0xFE8: UARTPeriphID2 Register
247    uartperiphid2: ReadPure<u32>,
248    /// 0xFEC: UARTPeriphID3 Register
249    uartperiphid3: ReadPure<u32>,
250    /// 0xFF0: UARTPCellID0 Register
251    uartpcellid0: ReadPure<u32>,
252    /// 0xFF4: UARTPCellID1 Register
253    uartpcellid1: ReadPure<u32>,
254    /// 0xFF8: UARTPCellID2 Register
255    uartpcellid2: ReadPure<u32>,
256    /// 0xFFC: UARTPCellID3 Register
257    uartpcellid3: ReadPure<u32>,
258}
259
260// Config
261
262/// Data bit count
263#[derive(Clone, Copy, Debug, Eq, PartialEq)]
264pub enum DataBits {
265    Bits5,
266    Bits6,
267    Bits7,
268    Bits8,
269}
270
271/// Parity
272#[derive(Clone, Copy, Debug, Eq, PartialEq)]
273pub enum Parity {
274    None,
275    Even,
276    Odd,
277    One,
278    Zero,
279}
280
281/// Stop bit count
282#[derive(Clone, Copy, Debug, Eq, PartialEq)]
283pub enum StopBits {
284    One,
285    Two,
286}
287
288/// UART line config structure
289#[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/// RX/TX interrupt FIFO levels
297#[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/// UART peripheral identification structure
307#[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    /// Check if the identification block describes a valid PL011 peripheral
322    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/// PL011 UART error type
331#[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
345/// PL011 UART implementation
346pub struct Uart<'a> {
347    regs: UniqueMmioPointer<'a, PL011Registers>,
348}
349
350impl<'a> Uart<'a> {
351    /// Creates new UART instance.
352    pub fn new(regs: UniqueMmioPointer<'a, PL011Registers>) -> Self {
353        Self { regs }
354    }
355
356    /// Configure and enable UART
357    pub fn enable(&mut self, config: LineConfig, baud_rate: u32, sysclk: u32) -> Result<(), Error> {
358        // Baud rate
359        let (uartibrd, uartfbrd) = Self::calculate_baud_rate_divisor(baud_rate, sysclk)?;
360
361        // Line control register
362        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    /// Disable UART
394    pub fn disable(&mut self) {
395        field!(self.regs, uartcr).write(ControlRegister::empty());
396    }
397
398    /// Check if receive FIFO is empty
399    pub fn is_rx_fifo_empty(&self) -> bool {
400        self.flags().contains(FlagsRegister::RXFE)
401    }
402
403    /// Check if receive FIFO is full
404    pub fn is_rx_fifo_full(&self) -> bool {
405        self.flags().contains(FlagsRegister::RXFF)
406    }
407
408    /// Check if transmit FIFO is empty
409    pub fn is_tx_fifo_empty(&self) -> bool {
410        self.flags().contains(FlagsRegister::TXFE)
411    }
412
413    /// Check if transmit FIFO is full
414    pub fn is_tx_fifo_full(&self) -> bool {
415        self.flags().contains(FlagsRegister::TXFF)
416    }
417
418    /// Check if UART is busy
419    pub fn is_busy(&self) -> bool {
420        self.flags().contains(FlagsRegister::BUSY)
421    }
422
423    /// Reads and returns the flag register.
424    fn flags(&self) -> FlagsRegister {
425        field_shared!(self.regs, uartfr).read()
426    }
427
428    /// Non-blocking read of a single byte from the UART.
429    ///
430    /// Returns `Ok(None)` if no data is available to read.
431    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    /// Non-blocking write of a single byte to the UART
454    pub fn write_word(&mut self, word: u8) {
455        field!(self.regs, uartdr).write(word as u32);
456    }
457
458    /// Read UART peripheral identification structure
459    pub fn read_identification(&self) -> Identification {
460        // SAFETY: The caller of UniqueMmioPointer::new promised that it wraps a valid and unique
461        // register block.
462        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        // baud_div = sysclk / (baud_rate * 16)
481        // baud_div_bits = (baud_div * 2^7 + 1) / 2
482        // After simplifying:
483        // baud_div_bits = ((sysclk * 8 / baud_rate) + 1) / 2
484        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    /// Sets trigger levels for RX and TX interrupts.
504    /// The interrupts are generated when the fill level progresses through the trigger level.
505    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    /// Reads the raw interrupt status register.
512    pub fn raw_interrupt_status(&self) -> Interrupts {
513        field_shared!(self.regs, uartris).read()
514    }
515
516    /// Reads the masked interrupt status register.
517    pub fn masked_interrupt_status(&self) -> Interrupts {
518        field_shared!(self.regs, uartmis).read()
519    }
520
521    /// Returns the current set of interrupt masks.
522    pub fn interrupt_masks(&self) -> Interrupts {
523        field_shared!(self.regs, uartimsc).read()
524    }
525
526    /// Sets the interrupt masks.
527    pub fn set_interrupt_masks(&mut self, masks: Interrupts) {
528        field!(self.regs, uartimsc).write(masks)
529    }
530
531    /// Clears the given set of interrupts.
532    pub fn clear_interrupts(&mut self, interrupts: Interrupts) {
533        field!(self.regs, uarticr).write(interrupts)
534    }
535}
536
537// SAFETY: An `&Uart` only allows operations which read registers, which can safely be done from
538// multiple threads simultaneously.
539unsafe 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            // Wait until there is room in the TX buffer.
545            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        // Example 3-1 from PL011 TRM
603        assert_eq!(Ok(()), uart.enable(config, 230400, 4_000_000));
604
605        assert_eq!(0x00, regs.reg_read(0x004)); // UARTSR_ECR
606        assert_eq!(1, regs.reg_read(0x024)); // UARTIBDR
607        assert_eq!(5, regs.reg_read(0x028)); // UARTFBDR
608        assert_eq!(0b01110000, regs.reg_read(0x02c)); // UARTLCR_H
609        assert_eq!(0x0301, regs.reg_read(0x030)); // UARTCR
610    }
611
612    #[test]
613    fn enable_example_baudrates() {
614        // Table 3-9
615        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)); // UARTIBDR
627            assert_eq!(0x5, regs.reg_read(0x028)); // UARTFBDR
628        }
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)); // UARTIBDR
642            assert_eq!(0xb, regs.reg_read(0x028)); // UARTFBDR
643        }
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)); // UARTIBDR
657            assert_eq!(0x10, regs.reg_read(0x028)); // UARTFBDR
658        }
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)); // UARTIBDR
672            assert_eq!(0x21, regs.reg_read(0x028)); // UARTFBDR
673        }
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)); // UARTIBDR
687            assert_eq!(0x17, regs.reg_read(0x028)); // UARTFBDR
688        }
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)); // UARTIBDR
702            assert_eq!(0xb, regs.reg_read(0x028)); // UARTFBDR
703        }
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)); // UARTIBDR
717            assert_eq!(0x2f, regs.reg_read(0x028)); // UARTFBDR
718        }
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            // 8 bits, even parity, 2 stop bits
778            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)); // UARTLCR_H
787        }
788
789        regs.clear();
790
791        {
792            // 6 bits, odd parity, 1 stop bit
793            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)); // UARTLCR_H
803        }
804
805        regs.clear();
806
807        {
808            // 5 bits, one parity, 1 stop bit
809            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)); // UARTLCR_H
819        }
820
821        {
822            // 5 bits, zero paraty, 2 stop bit
823            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)); // UARTLCR_H
833        }
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)); // UARTCR
849    }
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}