arm_pl011_uart/
embedded_hal_nb.rs

1// SPDX-FileCopyrightText: Copyright The arm-pl011-uart Contributors.
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use crate::{Error, Uart};
5use embedded_hal_nb::{
6    nb,
7    serial::{self, ErrorKind, ErrorType, Read, Write},
8};
9
10impl ErrorType for Uart<'_> {
11    type Error = Error;
12}
13
14impl serial::Error for Error {
15    fn kind(&self) -> serial::ErrorKind {
16        match self {
17            Error::InvalidParameter => ErrorKind::Other,
18            Error::Overrun => ErrorKind::Overrun,
19            Error::Break => ErrorKind::Other,
20            Error::Parity => ErrorKind::Parity,
21            Error::Framing => ErrorKind::FrameFormat,
22        }
23    }
24}
25
26impl Write for Uart<'_> {
27    fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
28        if self.is_tx_fifo_full() {
29            return Err(nb::Error::WouldBlock);
30        }
31
32        self.write_word(word);
33
34        Ok(())
35    }
36
37    fn flush(&mut self) -> nb::Result<(), Self::Error> {
38        if self.is_busy() {
39            Err(nb::Error::WouldBlock)
40        } else {
41            Ok(())
42        }
43    }
44}
45
46impl Read for Uart<'_> {
47    fn read(&mut self) -> nb::Result<u8, Self::Error> {
48        match self.read_word() {
49            Ok(None) => Err(nb::Error::WouldBlock),
50            Ok(Some(word)) => Ok(word),
51            Err(err) => Err(nb::Error::Other(err)),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use crate::tests::FakePL011Registers;
60
61    #[test]
62    fn error_kind() {
63        assert_eq!(
64            ErrorKind::Other,
65            serial::Error::kind(&Error::InvalidParameter)
66        );
67
68        assert_eq!(
69            serial::ErrorKind::Overrun,
70            serial::Error::kind(&Error::Overrun)
71        );
72
73        assert_eq!(ErrorKind::Other, serial::Error::kind(&Error::Break));
74
75        assert_eq!(ErrorKind::Parity, serial::Error::kind(&Error::Parity));
76
77        assert_eq!(ErrorKind::FrameFormat, serial::Error::kind(&Error::Framing));
78    }
79
80    #[test]
81    fn serial_write() {
82        let mut regs = FakePL011Registers::new();
83
84        {
85            let mut uart = regs.uart_for_test();
86            assert_eq!(Ok(()), Write::write(&mut uart, 0x41));
87            assert_eq!(0x41, regs.reg_read(0x000));
88        }
89
90        regs.clear();
91
92        {
93            regs.reg_write(0x018, 1 << 5);
94            let mut uart = regs.uart_for_test();
95            assert_eq!(Err(nb::Error::WouldBlock), Write::write(&mut uart, 0x41));
96        }
97
98        regs.clear();
99
100        {
101            let mut uart = regs.uart_for_test();
102            assert_eq!(Ok(()), Write::flush(&mut uart));
103        }
104        regs.clear();
105
106        {
107            regs.reg_write(0x018, 1 << 3);
108            let mut uart = regs.uart_for_test();
109            assert_eq!(Err(nb::Error::WouldBlock), Write::flush(&mut uart));
110        }
111    }
112
113    #[test]
114    fn serial_read() {
115        let mut regs = FakePL011Registers::new();
116
117        {
118            regs.reg_write(0x000, 0x41);
119
120            let mut uart = regs.uart_for_test();
121            assert_eq!(Ok(0x41), Read::read(&mut uart));
122        }
123
124        regs.clear();
125
126        {
127            regs.reg_write(0x000, 0x41);
128
129            let mut uart = regs.uart_for_test();
130            assert_eq!(Ok(0x41), Read::read(&mut uart));
131        }
132
133        regs.clear();
134
135        {
136            regs.reg_write(0x000, 1 << 11);
137
138            let mut uart = regs.uart_for_test();
139            assert_eq!(Err(nb::Error::Other(Error::Overrun)), Read::read(&mut uart));
140        }
141
142        regs.clear();
143
144        {
145            regs.reg_write(0x018, 1 << 4);
146
147            let mut uart = regs.uart_for_test();
148            assert_eq!(Err(nb::Error::WouldBlock), Read::read(&mut uart));
149        }
150    }
151}