1use core::convert::Infallible;
3
4use crate::registers::{self, Registers, Status};
5
6#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
8pub struct RxErrors {
9 parity: bool,
10 frame: bool,
11 overrun: bool,
12}
13
14impl RxErrors {
15 pub const fn new() -> Self {
17 Self {
18 parity: false,
19 frame: false,
20 overrun: false,
21 }
22 }
23
24 pub const fn parity(&self) -> bool {
26 self.parity
27 }
28
29 pub const fn frame(&self) -> bool {
31 self.frame
32 }
33
34 pub const fn overrun(&self) -> bool {
36 self.overrun
37 }
38
39 pub const fn has_errors(&self) -> bool {
41 self.parity || self.frame || self.overrun
42 }
43}
44
45pub struct Rx {
50 pub(crate) regs: registers::MmioRegisters<'static>,
51 pub(crate) errors: Option<RxErrors>,
52}
53
54impl Rx {
55 #[inline]
69 pub const unsafe fn steal(base_addr: usize) -> Self {
70 Self {
71 regs: unsafe { Registers::new_mmio_at(base_addr) },
72 errors: None,
73 }
74 }
75
76 #[inline]
81 pub fn read_fifo(&mut self) -> nb::Result<u8, Infallible> {
82 let status_reg = self.regs.read_stat_reg();
83 if !status_reg.rx_fifo_valid_data() {
84 return Err(nb::Error::WouldBlock);
85 }
86 let val = self.read_fifo_unchecked();
87 if let Some(errors) = handle_status_reg_errors(&status_reg) {
88 self.errors = Some(errors);
89 }
90 Ok(val)
91 }
92
93 #[inline(always)]
95 pub fn read_fifo_unchecked(&mut self) -> u8 {
96 self.regs.read_rx_fifo().data()
97 }
98
99 #[inline(always)]
101 pub fn has_data(&self) -> bool {
102 self.regs.read_stat_reg().rx_fifo_valid_data()
103 }
104
105 #[inline]
109 pub fn read_whole_fifo(&mut self, buf: &mut [u8; 16]) -> usize {
110 let mut read = 0;
111 while read < buf.len() {
112 match self.read_fifo() {
113 Ok(byte) => {
114 buf[read] = byte;
115 read += 1;
116 }
117 Err(nb::Error::WouldBlock) => break,
118 }
119 }
120 read
121 }
122
123 #[inline]
127 pub fn on_interrupt_rx(&mut self, buf: &mut [u8; 16]) -> usize {
128 self.read_whole_fifo(buf)
129 }
130
131 pub fn read_and_clear_last_error(&mut self) -> Option<RxErrors> {
135 let errors = self.errors?;
136 self.errors = None;
137 Some(errors)
138 }
139}
140
141impl embedded_hal_nb::serial::ErrorType for Rx {
142 type Error = Infallible;
143}
144
145impl embedded_hal_nb::serial::Read for Rx {
146 #[inline]
147 fn read(&mut self) -> nb::Result<u8, Self::Error> {
148 self.read_fifo()
149 }
150}
151
152impl embedded_io::ErrorType for Rx {
153 type Error = Infallible;
154}
155
156impl embedded_io::Read for Rx {
157 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
158 if buf.is_empty() {
159 return Ok(0);
160 }
161 while !self.has_data() {}
162 let mut read = 0;
163 for byte in buf.iter_mut() {
164 match self.read_fifo() {
165 Ok(data) => {
166 *byte = data;
167 read += 1;
168 }
169 Err(nb::Error::WouldBlock) => break,
170 }
171 }
172 Ok(read)
173 }
174}
175
176pub const fn handle_status_reg_errors(status_reg: &Status) -> Option<RxErrors> {
178 let mut errors = RxErrors::new();
179 if status_reg.frame_error() {
180 errors.frame = true;
181 }
182 if status_reg.parity_error() {
183 errors.parity = true;
184 }
185 if status_reg.overrun_error() {
186 errors.overrun = true;
187 }
188 if !errors.has_errors() {
189 return None;
190 }
191 Some(errors)
192}