1mod registers;
9
10use bitflags::Flags;
11use rdif_serial::{
12 Config, ConfigError, DataBits, IrqRxSink, Parity, RxErrorFlags, RxFlag, RxSample,
13 SerialEventSet, SerialIrqEvent, SplitUart, StopBits, UartInfo, UartIrq, UartParts, UartPort,
14};
15use registers::*;
16
17use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
18
19pub mod dw_apb;
20#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
21mod pio;
22pub mod rockchip_fiq;
23mod mmio;
25
26pub use dw_apb::*;
27pub use mmio::*;
28#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
29pub use pio::*;
30pub use rockchip_fiq::*;
31
32pub trait Kind: Clone + Send + Sync + 'static {
33 fn read_reg(&self, reg: u8) -> u8;
34 fn write_reg(&self, reg: u8, val: u8);
35 fn get_base(&self) -> usize;
36
37 fn ack_busy_detect(&self) {}
38
39 fn set_baudrate(&self, clock_freq: u32, baudrate: u32) -> Result<(), ConfigError> {
40 if baudrate == 0 || clock_freq == 0 {
41 return Err(ConfigError::InvalidBaudrate);
42 }
43
44 let divisor = clock_freq / (16 * baudrate);
45 if divisor == 0 || divisor > 0xFFFF {
46 return Err(ConfigError::InvalidBaudrate);
47 }
48
49 let lcr: LineControlFlags = self.read_flags(UART_LCR);
50 self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
51
52 self.write_reg(UART_DLL, (divisor & 0xFF) as u8);
53 self.write_reg(UART_DLH, ((divisor >> 8) & 0xFF) as u8);
54
55 self.write_flags(UART_LCR, lcr);
56
57 Ok(())
58 }
59
60 fn baudrate(&self, clock_freq: u32) -> u32 {
61 let lcr: LineControlFlags = self.read_flags(UART_LCR);
62 self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
63
64 let dll = self.read_reg(UART_DLL) as u16;
65 let dlh = self.read_reg(UART_DLH) as u16;
66
67 self.write_flags(UART_LCR, lcr);
68
69 let divisor = dll | (dlh << 8);
70
71 if divisor == 0 {
72 return 0;
73 }
74
75 clock_freq / (16 * divisor as u32)
76 }
77
78 fn init(&self) {
79 self.write_flags(UART_IER, InterruptEnableFlags::empty());
80 self.write_flags(
81 UART_FCR,
82 FifoControlFlags::ENABLE_FIFO
83 | FifoControlFlags::CLEAR_RECEIVER_FIFO
84 | FifoControlFlags::CLEAR_TRANSMITTER_FIFO
85 | FifoControlFlags::TRIGGER_1_BYTE,
86 );
87
88 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
89 mcr.insert(
90 ModemControlFlags::DATA_TERMINAL_READY
91 | ModemControlFlags::REQUEST_TO_SEND
92 | ModemControlFlags::OUT_2,
93 );
94 self.write_flags(UART_MCR, mcr);
95 }
96
97 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
99 F::from_bits_retain(self.read_reg(reg))
100 }
101
102 fn write_flags<F: Flags<Bits = u8>>(&self, reg: u8, val: F) {
103 self.write_reg(reg, val.bits());
104 }
105}
106
107pub struct Ns16550<T: Kind> {
108 pub(crate) base: T,
109 pub(crate) clock_freq: u32,
110 pub(crate) saved_lsr: LineStatusFlags,
111}
112
113pub struct Ns16550Irq<T: Kind> {
115 base: T,
116 saved_lsr: LineStatusFlags,
117}
118
119impl<T: Kind> Ns16550Irq<T> {
120 fn next_event(&self) -> Option<SerialEventSet> {
121 let iir: InterruptIdentificationFlags = self.base.read_flags(UART_IIR);
122 if iir.bits() & (UART_IIR_ID | UART_IIR_NO_INT) == UART_IIR_BUSY {
123 return Some(SerialEventSet::BUSY_DETECT);
124 }
125 if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
126 return None;
127 }
128
129 let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
130 let event = if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
131 SerialEventSet::RX_STATUS
132 } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE {
133 SerialEventSet::RX_DATA
134 } else if interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT {
135 SerialEventSet::RX_TIMEOUT
136 } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
137 SerialEventSet::TX_SPACE
138 } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
139 SerialEventSet::MODEM_STATUS
140 } else {
141 SerialEventSet::FAULT
142 };
143 Some(event)
144 }
145
146 fn ack_modem_status(&self) {
147 let _: ModemStatusFlags = self.base.read_flags(UART_MSR);
148 }
149
150 fn ack_busy_detect(&self) {
151 self.base.ack_busy_detect();
152 }
153
154 fn mask(&self, events: SerialEventSet) {
155 let mut ier: InterruptEnableFlags = self.base.read_flags(UART_IER);
156 ier.remove(interrupt_enable_for_events(events));
157 self.base.write_flags(UART_IER, ier);
158 }
159}
160
161impl<T: Kind> UartIrq for Ns16550Irq<T> {
162 fn handle(&mut self, rx: &mut dyn IrqRxSink) -> Option<SerialIrqEvent> {
163 const IRQ_PASS_BUDGET: usize = 32;
164 const RX_SAMPLE_BUDGET: usize = 256;
165
166 let mut event = SerialIrqEvent::default();
167 let mut rx_samples = 0;
168 for _ in 0..IRQ_PASS_BUDGET {
169 let Some(current) = self.next_event() else {
170 break;
171 };
172 event.events |= current;
173 if current.intersects(SerialEventSet::RX) {
174 let before = rx_samples;
175 while rx_samples < RX_SAMPLE_BUDGET {
176 let Some(sample) = read_rx_sample(&self.base, &mut self.saved_lsr) else {
177 break;
178 };
179 event.rx_errors |= rx_errors_from_sample(sample);
180 rx.push(sample);
181 rx_samples += 1;
182 }
183 if rx_samples == RX_SAMPLE_BUDGET || rx_samples == before {
184 break;
185 }
186 }
187 if current.contains(SerialEventSet::MODEM_STATUS) {
188 self.ack_modem_status();
189 }
190 if current.contains(SerialEventSet::BUSY_DETECT) {
191 self.ack_busy_detect();
192 }
193 if current.contains(SerialEventSet::FAULT) {
194 self.base
195 .write_flags(UART_IER, InterruptEnableFlags::empty());
196 break;
197 }
198
199 let rearm = current & SerialEventSet::TX_SPACE;
200 if !rearm.is_empty() {
201 self.mask(rearm);
202 event.rearm |= rearm;
203 }
204 }
205
206 (!event.events.is_empty()).then_some(event)
207 }
208}
209
210impl<T: Kind> UartPort for Ns16550<T> {
211 fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
212 self.write_flags(UART_IER, InterruptEnableFlags::empty());
213 self.set_config(config)?;
214 self.enable_fifo(true);
215
216 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
217 mcr.insert(
218 ModemControlFlags::DATA_TERMINAL_READY
219 | ModemControlFlags::REQUEST_TO_SEND
220 | ModemControlFlags::OUT_2,
221 );
222 self.write_flags(UART_MCR, mcr);
223 self.saved_lsr = LineStatusFlags::empty();
224 Ok(())
225 }
226
227 fn shutdown(&mut self) {
228 self.close();
229 }
230
231 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
232 if let Some(baudrate) = config.baudrate {
234 self.set_baudrate_internal(baudrate)?;
235 }
236
237 if let Some(data_bits) = config.data_bits {
239 self.set_data_bits_internal(data_bits)?;
240 }
241
242 if let Some(stop_bits) = config.stop_bits {
244 self.set_stop_bits_internal(stop_bits)?;
245 }
246
247 if let Some(parity) = config.parity {
249 self.set_parity_internal(parity)?;
250 }
251 Ok(())
252 }
253
254 fn read_rx(&mut self) -> Option<RxSample> {
255 Ns16550::read_rx(self)
256 }
257
258 fn write_tx(&mut self, bytes: &[u8]) -> usize {
259 self.try_write(bytes)
260 }
261
262 fn tx_idle(&mut self) -> bool {
263 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
264 lsr.contains(
265 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY | LineStatusFlags::TRANSMITTER_EMPTY,
266 )
267 }
268
269 fn mask_all(&mut self) {
270 self.write_flags(UART_IER, InterruptEnableFlags::empty());
271 }
272
273 fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
274 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
275 ier.insert(interrupt_enable_for_events(sources));
276 self.write_flags(UART_IER, ier);
277
278 let lsr = self.read_lsr_preserving();
279 let mut ready = SerialEventSet::empty();
280 if sources.intersects(SerialEventSet::RX)
281 && lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK)
282 {
283 ready |= if lsr.contains(LineStatusFlags::DATA_READY) {
284 SerialEventSet::RX_DATA
285 } else {
286 SerialEventSet::RX_STATUS
287 };
288 }
289 if sources.contains(SerialEventSet::TX_SPACE)
290 && lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY)
291 {
292 ready |= SerialEventSet::TX_SPACE;
293 }
294 if !ready.is_empty() {
295 ier.remove(interrupt_enable_for_events(ready));
296 self.write_flags(UART_IER, ier);
297 }
298 ready
299 }
300}
301
302impl<T: Kind> SplitUart for Ns16550<T> {
303 type Port = Self;
304 type Irq = Ns16550Irq<T>;
305
306 fn runtime_info(&self) -> UartInfo {
307 UartInfo {
308 name: "NS16550 UART",
309 register_base: self.base.get_base(),
310 initial_baudrate: self.base.baudrate(self.clock_freq),
311 }
312 }
313
314 fn split(self) -> UartParts<Self::Port, Self::Irq> {
315 let irq = Ns16550Irq {
316 base: self.base.clone(),
317 saved_lsr: LineStatusFlags::empty(),
318 };
319 UartParts::new(self, irq)
320 }
321}
322
323impl<T: Kind> PollingUart for Ns16550<T> {
324 fn poll_status(&mut self) -> SerialEvent {
325 Ns16550::poll_status(self)
326 }
327
328 fn write_byte(&mut self, byte: u8) {
329 Ns16550::write_byte(self, byte);
330 }
331
332 fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
333 Ns16550::read_byte(self, status)
334 }
335}
336
337impl<T: Kind> Ns16550<T> {
338 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
340 F::from_bits_retain(self.base.read_reg(reg))
341 }
342
343 fn write_flags<F: Flags<Bits = u8>>(&mut self, reg: u8, val: F) {
344 self.base.write_reg(reg, val.bits());
345 }
346
347 pub fn pending(&mut self, direction: SerialDirection) -> bool {
348 let lsr = self.read_lsr_preserving();
349 match direction {
350 SerialDirection::Input => lsr.contains(LineStatusFlags::DATA_READY),
351 SerialDirection::Output => lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY),
352 }
353 }
354
355 pub fn poll_status(&mut self) -> SerialEvent {
356 serial_event_from_lsr(self.read_lsr_preserving())
357 }
358
359 pub fn try_write(&mut self, bytes: &[u8]) -> usize {
360 let mut written = 0;
361 while written < bytes.len() {
362 let status = self.poll_status();
363 if !status.tx_ready() {
364 break;
365 }
366 self.write_byte(bytes[written]);
367 written += 1;
368 }
369 written
370 }
371
372 pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
373 let mut read_count = 0;
374 let mut first_error = None;
375 for byte in bytes.iter_mut() {
376 let status = self.poll_status();
377 if !status.rx_ready() && !status.rx_error() {
378 break;
379 }
380 let result = self.read_byte(status);
381 match result {
382 Some(Ok(b)) => {
383 *byte = b;
384 read_count += 1;
385 }
386 Some(Err(TransferError::Overrun(b))) => {
387 *byte = b;
388 read_count += 1;
389 first_error.get_or_insert(TransferError::Overrun(b));
390 }
391 Some(Err(e)) => {
392 first_error.get_or_insert(e);
393 }
394 None => break,
395 }
396 }
397 if let Some(kind) = first_error {
398 Err(TransBytesError {
399 bytes_transferred: read_count,
400 kind,
401 })
402 } else {
403 Ok(read_count)
404 }
405 }
406
407 pub fn write_byte(&mut self, byte: u8) {
408 self.base.write_reg(UART_THR, byte);
409 }
410
411 pub fn read_rx(&mut self) -> Option<RxSample> {
412 read_rx_sample(&self.base, &mut self.saved_lsr)
413 }
414
415 fn read_lsr_preserving(&mut self) -> LineStatusFlags {
416 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
417 self.saved_lsr
418 .insert(lsr & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
419 lsr | self.saved_lsr
420 }
421
422 pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
423 if !status.rx_ready() && !status.rx_error() {
424 return None;
425 }
426 if self.saved_lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
427 let b = self.base.read_reg(UART_RBR);
428 self.saved_lsr.remove(LineStatusFlags::OVERRUN_ERROR);
429 return Some(Err(TransferError::Overrun(b)));
430 }
431 if self.saved_lsr.contains(LineStatusFlags::PARITY_ERROR) {
432 let _ = self.base.read_reg(UART_RBR);
433 self.saved_lsr.remove(LineStatusFlags::PARITY_ERROR);
434 return Some(Err(TransferError::Parity));
435 }
436 if self.saved_lsr.contains(LineStatusFlags::FRAMING_ERROR) {
437 let _ = self.base.read_reg(UART_RBR);
438 self.saved_lsr.remove(LineStatusFlags::FRAMING_ERROR);
439 return Some(Err(TransferError::Framing));
440 }
441 if self.saved_lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
442 let _ = self.base.read_reg(UART_RBR);
443 self.saved_lsr.remove(LineStatusFlags::BREAK_INTERRUPT);
444 return Some(Err(TransferError::Break));
445 }
446 if status.rx_ready() {
447 return Some(Ok(self.base.read_reg(UART_RBR)));
448 }
449 None
450 }
451
452 pub fn open(&mut self) {
453 self.init_core();
454 }
455
456 pub fn close(&mut self) {
457 self.write_flags(UART_IER, InterruptEnableFlags::empty());
458
459 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
460 mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
461 self.write_flags(UART_MCR, mcr);
462 }
463
464 pub fn set_irq_mask(&mut self, events: SerialEventSet) {
465 self.write_flags(UART_IER, interrupt_enable_for_events(events));
466 }
467
468 pub fn get_irq_mask(&self) -> SerialEventSet {
469 let ier: InterruptEnableFlags = self.read_flags(UART_IER);
470 let mut events = SerialEventSet::empty();
471
472 if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
473 events |= SerialEventSet::RX_DATA;
474 }
475 if ier.contains(InterruptEnableFlags::RECEIVER_LINE_STATUS) {
476 events |= SerialEventSet::RX_STATUS;
477 }
478 if ier.contains(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY) {
479 events |= SerialEventSet::TX_SPACE;
480 }
481
482 events
483 }
484
485 pub fn is_16550_plus(&self) -> bool {
487 let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
490 fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
491 }
492
493 fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
495 self.base.set_baudrate(self.clock_freq, baudrate)
496 }
497
498 fn set_data_bits_internal(&mut self, bits: DataBits) -> Result<(), ConfigError> {
500 let wlen = match bits {
501 DataBits::Five => LineControlFlags::WORD_LENGTH_5,
502 DataBits::Six => LineControlFlags::WORD_LENGTH_6,
503 DataBits::Seven => LineControlFlags::WORD_LENGTH_7,
504 DataBits::Eight => LineControlFlags::WORD_LENGTH_8,
505 };
506
507 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
508 lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
510 lcr.insert(wlen);
511 self.write_flags(UART_LCR, lcr);
512
513 Ok(())
514 }
515
516 fn set_stop_bits_internal(&mut self, bits: StopBits) -> Result<(), ConfigError> {
518 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
519 match bits {
520 StopBits::One => lcr.remove(LineControlFlags::STOP_BITS),
521 StopBits::Two => lcr.insert(LineControlFlags::STOP_BITS),
522 }
523 self.write_flags(UART_LCR, lcr);
524 Ok(())
525 }
526
527 fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
529 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
530
531 lcr.remove(
533 LineControlFlags::PARITY_ENABLE
534 | LineControlFlags::EVEN_PARITY
535 | LineControlFlags::STICK_PARITY,
536 );
537
538 match parity {
540 Parity::None => {
541 }
543 Parity::Odd => {
544 lcr.insert(LineControlFlags::PARITY_ENABLE);
545 }
546 Parity::Even => {
547 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::EVEN_PARITY);
548 }
549 Parity::Mark => {
550 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::STICK_PARITY);
551 }
552 Parity::Space => {
553 lcr.insert(
554 LineControlFlags::PARITY_ENABLE
555 | LineControlFlags::EVEN_PARITY
556 | LineControlFlags::STICK_PARITY,
557 );
558 }
559 }
560
561 self.write_flags(UART_LCR, lcr);
562 Ok(())
563 }
564
565 pub fn enable_fifo(&mut self, enable: bool) {
567 if enable {
568 let mut fcr = FifoControlFlags::ENABLE_FIFO;
569 fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
570 fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
571 fcr.insert(FifoControlFlags::TRIGGER_8_BYTES);
575 self.write_flags(UART_FCR, fcr);
576 if self.is_fifo_enabled() {
577 return;
578 }
579 }
580 self.write_flags(UART_FCR, FifoControlFlags::empty());
581 }
582
583 pub fn set_fifo_trigger_level(&mut self, level: u8) {
585 if !self.is_16550_plus() {
586 return;
587 }
588
589 let trigger_value = match level {
590 0..=3 => FifoControlFlags::TRIGGER_1_BYTE,
591 4..=7 => FifoControlFlags::TRIGGER_4_BYTES,
592 8..=11 => FifoControlFlags::TRIGGER_8_BYTES,
593 _ => FifoControlFlags::TRIGGER_14_BYTES,
594 };
595
596 let mut fcr: FifoControlFlags = self.read_flags(UART_FCR);
598 fcr.remove(FifoControlFlags::TRIGGER_LEVEL_MASK);
599 fcr.insert(trigger_value);
600 self.write_flags(UART_FCR, fcr);
601 }
602
603 fn init_core(&mut self) {
605 self.base.init();
606 }
607
608 pub fn is_fifo_enabled(&self) -> bool {
610 if !self.is_16550_plus() {
611 return false;
612 }
613 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
615 iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
616 }
617}
618
619fn read_rx_sample<T: Kind>(base: &T, saved_lsr: &mut LineStatusFlags) -> Option<RxSample> {
620 let current: LineStatusFlags = base.read_flags(UART_LSR);
621 saved_lsr.insert(current & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
622 let lsr = current | *saved_lsr;
623 if !lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK) {
624 return None;
625 }
626
627 let byte = lsr
628 .contains(LineStatusFlags::DATA_READY)
629 .then(|| base.read_reg(UART_RBR));
630 let flag = if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
631 RxFlag::Break
632 } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
633 RxFlag::Parity
634 } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
635 RxFlag::Framing
636 } else {
637 RxFlag::Normal
638 };
639 let overrun = lsr.contains(LineStatusFlags::OVERRUN_ERROR);
640 saved_lsr.remove(LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR);
641
642 Some(RxSample {
643 byte,
644 flag,
645 overrun,
646 })
647}
648
649fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
650 let mut errors = match sample.flag {
651 RxFlag::Normal => RxErrorFlags::empty(),
652 RxFlag::Break => RxErrorFlags::BREAK,
653 RxFlag::Parity => RxErrorFlags::PARITY,
654 RxFlag::Framing => RxErrorFlags::FRAMING,
655 };
656 if sample.overrun {
657 errors |= RxErrorFlags::OVERRUN;
658 }
659 errors
660}
661
662fn interrupt_enable_for_events(events: SerialEventSet) -> InterruptEnableFlags {
663 let mut ier = InterruptEnableFlags::empty();
664 if events.intersects(SerialEventSet::RX) {
665 ier.insert(
666 InterruptEnableFlags::RECEIVED_DATA_AVAILABLE
667 | InterruptEnableFlags::RECEIVER_LINE_STATUS,
668 );
669 }
670 if events.contains(SerialEventSet::TX_SPACE) {
671 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
672 }
673 ier
674}
675
676fn serial_event_from_lsr(lsr: LineStatusFlags) -> SerialEvent {
677 let mut event = SerialEvent::empty();
678 if lsr.contains(LineStatusFlags::DATA_READY) {
679 event |= SerialEvent::RX_READY;
680 }
681 if lsr.intersects(
682 LineStatusFlags::PARITY_ERROR
683 | LineStatusFlags::FRAMING_ERROR
684 | LineStatusFlags::BREAK_INTERRUPT,
685 ) {
686 event |= SerialEvent::RX_ERROR;
687 }
688 if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
689 event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
690 }
691 if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
692 event |= SerialEvent::TX_READY;
693 }
694 event
695}
696
697#[cfg(test)]
698mod tests {
699 use core::sync::atomic::{AtomicU8, AtomicUsize, Ordering};
700 use std::{
701 sync::{Arc, Mutex, MutexGuard},
702 vec::Vec,
703 };
704
705 use super::*;
706
707 static REGS: [AtomicU8; 8] = [const { AtomicU8::new(0) }; 8];
708 static DLL_REG: AtomicU8 = AtomicU8::new(0);
709 static DLH_REG: AtomicU8 = AtomicU8::new(0);
710 static THR_WRITES: AtomicUsize = AtomicUsize::new(0);
711 static RBR_READS: AtomicUsize = AtomicUsize::new(0);
712 static LSR_READS: AtomicUsize = AtomicUsize::new(0);
713 static LAST_FCR_WRITE: AtomicU8 = AtomicU8::new(0);
714 static TEST_LOCK: Mutex<()> = Mutex::new(());
715
716 #[derive(Default)]
717 struct CollectRx(Vec<RxSample>);
718
719 impl IrqRxSink for CollectRx {
720 fn push(&mut self, sample: RxSample) {
721 self.0.push(sample);
722 }
723 }
724
725 fn handle_irq(irq: &mut impl UartIrq) -> (Option<SerialIrqEvent>, Vec<RxSample>) {
726 let mut rx = CollectRx::default();
727 let event = irq.handle(&mut rx);
728 (event, rx.0)
729 }
730
731 #[derive(Clone)]
732 struct MockKind;
733
734 impl Kind for MockKind {
735 fn read_reg(&self, reg: u8) -> u8 {
736 let dlab = REGS[UART_LCR as usize].load(Ordering::SeqCst)
737 & LineControlFlags::DIVISOR_LATCH_ACCESS.bits()
738 != 0;
739 if dlab {
740 return match reg {
741 UART_DLL => DLL_REG.load(Ordering::SeqCst),
742 UART_DLH => DLH_REG.load(Ordering::SeqCst),
743 _ => REGS[reg as usize].load(Ordering::SeqCst),
744 };
745 }
746
747 let value = REGS[reg as usize].load(Ordering::SeqCst);
748 if reg == UART_LSR {
749 LSR_READS.fetch_add(1, Ordering::SeqCst);
750 }
751 if reg == UART_RBR {
752 RBR_READS.fetch_add(1, Ordering::SeqCst);
753 REGS[UART_LSR as usize].fetch_and(
754 !(LineStatusFlags::ERROR_MASK | LineStatusFlags::DATA_READY).bits(),
755 Ordering::SeqCst,
756 );
757 } else if reg == UART_MSR {
758 REGS[UART_MSR as usize]
759 .fetch_and(!ModemStatusFlags::DELTA_MASK.bits(), Ordering::SeqCst);
760 }
761 value
762 }
763
764 fn write_reg(&self, reg: u8, val: u8) {
765 let dlab = REGS[UART_LCR as usize].load(Ordering::SeqCst)
766 & LineControlFlags::DIVISOR_LATCH_ACCESS.bits()
767 != 0;
768 if dlab {
769 match reg {
770 UART_DLL => {
771 DLL_REG.store(val, Ordering::SeqCst);
772 return;
773 }
774 UART_DLH => {
775 DLH_REG.store(val, Ordering::SeqCst);
776 return;
777 }
778 _ => {}
779 }
780 }
781
782 REGS[reg as usize].store(val, Ordering::SeqCst);
783 if reg == UART_FCR {
784 LAST_FCR_WRITE.store(val, Ordering::SeqCst);
785 if val & FifoControlFlags::ENABLE_FIFO.bits() != 0 {
786 REGS[UART_IIR as usize].fetch_or(
787 InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
788 Ordering::SeqCst,
789 );
790 } else {
791 REGS[UART_IIR as usize].fetch_and(
792 !InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
793 Ordering::SeqCst,
794 );
795 }
796 }
797 if reg == UART_THR {
798 let iir = REGS[UART_IIR as usize].load(Ordering::SeqCst);
799 if iir & InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits() == 0 {
800 REGS[UART_LSR as usize].fetch_and(
801 !LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
802 Ordering::SeqCst,
803 );
804 } else {
805 let writes = THR_WRITES.fetch_add(1, Ordering::SeqCst) + 1;
806 if writes >= UART_FIFO_SIZE as usize {
807 REGS[UART_LSR as usize].fetch_and(
808 !LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
809 Ordering::SeqCst,
810 );
811 }
812 }
813 }
814 }
815
816 fn get_base(&self) -> usize {
817 0x1000
818 }
819 }
820
821 #[derive(Clone)]
822 struct FloodKind {
823 rbr_reads: Arc<AtomicUsize>,
824 }
825
826 impl Kind for FloodKind {
827 fn read_reg(&self, reg: u8) -> u8 {
828 match reg {
829 UART_IIR => InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
830 UART_LSR => LineStatusFlags::DATA_READY.bits(),
831 UART_RBR => self.rbr_reads.fetch_add(1, Ordering::SeqCst) as u8,
832 _ => 0,
833 }
834 }
835
836 fn write_reg(&self, _reg: u8, _val: u8) {}
837
838 fn get_base(&self) -> usize {
839 0x2000
840 }
841 }
842
843 fn reset_regs() {
844 for reg in ®S {
845 reg.store(0, Ordering::SeqCst);
846 }
847 DLL_REG.store(0, Ordering::SeqCst);
848 DLH_REG.store(0, Ordering::SeqCst);
849 THR_WRITES.store(0, Ordering::SeqCst);
850 RBR_READS.store(0, Ordering::SeqCst);
851 LSR_READS.store(0, Ordering::SeqCst);
852 LAST_FCR_WRITE.store(0, Ordering::SeqCst);
853 }
854
855 fn serial() -> (MutexGuard<'static, ()>, Ns16550<MockKind>) {
856 let guard = TEST_LOCK.lock().unwrap_or_else(|error| error.into_inner());
857 reset_regs();
858 (
859 guard,
860 Ns16550 {
861 base: MockKind,
862 clock_freq: 1_843_200,
863 saved_lsr: LineStatusFlags::empty(),
864 },
865 )
866 }
867
868 fn started_parts(
869 uart: Ns16550<MockKind>,
870 ) -> UartParts<Ns16550<MockKind>, Ns16550Irq<MockKind>> {
871 let mut parts = uart.split();
872 parts.port.startup(&Config::new()).unwrap();
873 parts
874 }
875
876 #[test]
877 fn baudrate_reads_divisor_latch_without_consuming_rx_register() {
878 let (_guard, uart) = serial();
879 let original_lcr = LineControlFlags::WORD_LENGTH_8 | LineControlFlags::STOP_BITS;
880 REGS[UART_LCR as usize].store(original_lcr.bits(), Ordering::SeqCst);
881 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
882 REGS[UART_RBR as usize].store(0, Ordering::SeqCst);
883 REGS[UART_IER as usize].store(0, Ordering::SeqCst);
884 DLL_REG.store(1, Ordering::SeqCst);
885 DLH_REG.store(0, Ordering::SeqCst);
886
887 assert_eq!(uart.runtime_info().initial_baudrate, 115_200);
888 assert_eq!(
889 REGS[UART_LCR as usize].load(Ordering::SeqCst),
890 original_lcr.bits()
891 );
892 assert!(
893 LineStatusFlags::from_bits_retain(REGS[UART_LSR as usize].load(Ordering::SeqCst))
894 .contains(LineStatusFlags::DATA_READY)
895 );
896 }
897
898 #[test]
899 fn pending_output_preserves_rx_error_latch() {
900 let (_guard, mut uart) = serial();
901 REGS[UART_LSR as usize].store(
902 (LineStatusFlags::TRANSMITTER_HOLDING_EMPTY | LineStatusFlags::PARITY_ERROR).bits(),
903 Ordering::SeqCst,
904 );
905
906 assert!(uart.pending(SerialDirection::Output));
907
908 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
909 let mut buf = [0];
910 let err = uart
911 .try_read(&mut buf)
912 .expect_err("saved parity error should be reported by next read");
913 assert_eq!(err.bytes_transferred, 0);
914 assert_eq!(err.kind, TransferError::Parity);
915 }
916
917 #[test]
918 fn try_write_stops_when_tx_fifo_becomes_full() {
919 let (_guard, mut uart) = serial();
920 REGS[UART_LSR as usize].store(
921 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
922 Ordering::SeqCst,
923 );
924
925 assert_eq!(uart.try_write(b"ab"), 1);
926 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
927 }
928
929 #[test]
930 fn try_write_fills_enabled_tx_fifo_in_one_pass() {
931 let (_guard, mut uart) = serial();
932 REGS[UART_LSR as usize].store(
933 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
934 Ordering::SeqCst,
935 );
936 REGS[UART_IIR as usize].store(
937 InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
938 Ordering::SeqCst,
939 );
940
941 assert_eq!(uart.try_write(b"abcdefghijklmnopq"), 16);
942 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'p');
943 }
944
945 #[test]
946 fn open_enables_modem_interrupt_output_gate() {
947 let (_guard, mut uart) = serial();
948
949 uart.open();
950
951 let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
952 assert!(fcr.contains(FifoControlFlags::ENABLE_FIFO));
953 assert!(fcr.contains(FifoControlFlags::CLEAR_RECEIVER_FIFO));
954 assert!(fcr.contains(FifoControlFlags::CLEAR_TRANSMITTER_FIFO));
955 let mcr =
956 ModemControlFlags::from_bits_retain(REGS[UART_MCR as usize].load(Ordering::SeqCst));
957 assert!(mcr.contains(ModemControlFlags::DATA_TERMINAL_READY));
958 assert!(mcr.contains(ModemControlFlags::REQUEST_TO_SEND));
959 assert!(mcr.contains(ModemControlFlags::OUT_2));
960 }
961
962 #[test]
963 fn startup_enables_fifo_before_checking_fifo_status() {
964 let (_guard, mut uart) = serial();
965
966 uart.startup(&Config::new()).unwrap();
967
968 let iir = InterruptIdentificationFlags::from_bits_retain(
969 REGS[UART_IIR as usize].load(Ordering::SeqCst),
970 );
971 assert!(iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK));
972 assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
973 }
974
975 #[test]
976 fn startup_uses_half_full_rx_trigger_for_deferred_service() {
977 let (_guard, mut uart) = serial();
978
979 uart.startup(&Config::new()).unwrap();
980
981 let fcr = FifoControlFlags::from_bits_retain(LAST_FCR_WRITE.load(Ordering::SeqCst));
982 assert_eq!(
983 fcr & FifoControlFlags::TRIGGER_LEVEL_MASK,
984 FifoControlFlags::TRIGGER_8_BYTES,
985 "deferred RX service must amortize IRQ wakeups at the Linux 16550A default trigger",
986 );
987 }
988
989 #[test]
990 fn try_read_empty_returns_zero() {
991 let (_guard, mut uart) = serial();
992 let mut buf = [0];
993
994 assert_eq!(uart.try_read(&mut buf), Ok(0));
995 }
996
997 #[test]
998 fn irq_reports_rx_error_and_buffers_fifo_data() {
999 let (_guard, uart) = serial();
1000 let mut parts = uart.split();
1001 REGS[UART_IIR as usize].store(
1002 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1003 Ordering::SeqCst,
1004 );
1005 REGS[UART_LSR as usize].store(
1006 (LineStatusFlags::DATA_READY | LineStatusFlags::OVERRUN_ERROR).bits(),
1007 Ordering::SeqCst,
1008 );
1009 REGS[UART_RBR as usize].store(0xab, Ordering::SeqCst);
1010
1011 let (event, samples) = handle_irq(&mut parts.irq);
1012 let event = event.unwrap();
1013 assert!(event.events.contains(SerialEventSet::RX_STATUS));
1014 assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1015 assert_eq!(
1016 samples,
1017 [RxSample {
1018 byte: Some(0xab),
1019 flag: RxFlag::Normal,
1020 overrun: true,
1021 }]
1022 );
1023 assert_eq!(RBR_READS.load(Ordering::SeqCst), 1);
1024 }
1025
1026 #[test]
1027 fn split_endpoints_service_rx_and_tx_fifo() {
1028 let (_guard, uart) = serial();
1029 let mut parts = started_parts(uart);
1030
1031 REGS[UART_IIR as usize].store(
1032 InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1033 Ordering::SeqCst,
1034 );
1035 REGS[UART_LSR as usize].store(
1036 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1037 Ordering::SeqCst,
1038 );
1039 let event = handle_irq(&mut parts.irq).0.unwrap();
1040 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1041 assert_eq!(parts.port.write_tx(b"ab"), 1);
1042 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1043
1044 REGS[UART_IIR as usize].store(
1045 InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
1046 Ordering::SeqCst,
1047 );
1048 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1049 REGS[UART_RBR as usize].store(b'z', Ordering::SeqCst);
1050 let (event, samples) = handle_irq(&mut parts.irq);
1051 let event = event.unwrap();
1052 assert!(event.events.contains(SerialEventSet::RX_DATA));
1053 assert_eq!(
1054 samples,
1055 [RxSample {
1056 byte: Some(b'z'),
1057 flag: RxFlag::Normal,
1058 overrun: false,
1059 }]
1060 );
1061 }
1062
1063 #[test]
1064 fn hard_irq_drains_rx_before_deferred_worker_can_overrun_fifo() {
1065 let (_guard, uart) = serial();
1066 let mut parts = started_parts(uart);
1067 REGS[UART_IIR as usize].store(
1068 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1069 Ordering::SeqCst,
1070 );
1071 REGS[UART_LSR as usize].store(
1072 (LineStatusFlags::DATA_READY | LineStatusFlags::PARITY_ERROR).bits(),
1073 Ordering::SeqCst,
1074 );
1075 LSR_READS.store(0, Ordering::SeqCst);
1076
1077 let (event, samples) = handle_irq(&mut parts.irq);
1078 let event = event.unwrap();
1079
1080 assert!(event.events.contains(SerialEventSet::RX_STATUS));
1081 assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1082 assert!(LSR_READS.load(Ordering::SeqCst) > 0);
1083 assert_eq!(
1084 RBR_READS.load(Ordering::SeqCst),
1085 1,
1086 "the hard IRQ must free a bounded hardware FIFO slot before the worker runs",
1087 );
1088 assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
1089 assert_eq!(REGS[UART_LSR as usize].load(Ordering::SeqCst), 0);
1090 assert_eq!(
1091 samples,
1092 [RxSample {
1093 byte: Some(0),
1094 flag: RxFlag::Parity,
1095 overrun: false,
1096 }]
1097 );
1098 }
1099
1100 #[test]
1101 fn hard_irq_rx_drain_is_bounded_to_256_samples() {
1102 let reads = Arc::new(AtomicUsize::new(0));
1103 let mut irq = Ns16550Irq {
1104 base: FloodKind {
1105 rbr_reads: reads.clone(),
1106 },
1107 saved_lsr: LineStatusFlags::empty(),
1108 };
1109
1110 let (event, samples) = handle_irq(&mut irq);
1111
1112 assert!(event.unwrap().events.contains(SerialEventSet::RX_DATA));
1113 assert_eq!(samples.len(), 256);
1114 assert_eq!(reads.load(Ordering::SeqCst), 256);
1115 }
1116
1117 #[test]
1118 fn irq_endpoint_does_not_synthesize_tx_irq_from_plain_lsr_ready() {
1119 let (_guard, uart) = serial();
1120 let mut parts = started_parts(uart);
1121 REGS[UART_IIR as usize].store(
1122 InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1123 Ordering::SeqCst,
1124 );
1125 REGS[UART_LSR as usize].store(
1126 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1127 Ordering::SeqCst,
1128 );
1129
1130 assert!(handle_irq(&mut parts.irq).0.is_none());
1131 }
1132
1133 #[test]
1134 fn hard_irq_does_not_claim_tx_ready_without_iir_pending() {
1135 let (_guard, uart) = serial();
1136 let mut parts = uart.split();
1137 parts.port.set_irq_mask(SerialEventSet::TX_SPACE);
1138 REGS[UART_IIR as usize].store(
1139 InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1140 Ordering::SeqCst,
1141 );
1142 REGS[UART_LSR as usize].store(
1143 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1144 Ordering::SeqCst,
1145 );
1146
1147 assert!(handle_irq(&mut parts.irq).0.is_none());
1148 assert!(parts.port.poll_status().tx_ready());
1149 }
1150
1151 #[test]
1152 fn hard_irq_does_not_claim_rx_ready_without_iir_pending() {
1153 let (_guard, uart) = serial();
1154 let mut parts = uart.split();
1155 parts.port.set_irq_mask(SerialEventSet::RX);
1156 REGS[UART_IIR as usize].store(
1157 InterruptIdentificationFlags::NO_INTERRUPT_PENDING.bits(),
1158 Ordering::SeqCst,
1159 );
1160 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1161
1162 assert!(handle_irq(&mut parts.irq).0.is_none());
1163 assert!(parts.port.poll_status().rx_ready());
1164 }
1165
1166 #[test]
1167 fn hard_irq_claims_and_clears_modem_status_interrupt() {
1168 let (_guard, uart) = serial();
1169 let mut parts = started_parts(uart);
1170
1171 REGS[UART_IIR as usize].store(
1172 InterruptIdentificationFlags::MODEM_STATUS.bits()
1173 | InterruptIdentificationFlags::FIFO_ENABLE_MASK.bits(),
1174 Ordering::SeqCst,
1175 );
1176 REGS[UART_MSR as usize].store(
1177 ModemStatusFlags::DELTA_CLEAR_TO_SEND.bits(),
1178 Ordering::SeqCst,
1179 );
1180
1181 let event = handle_irq(&mut parts.irq).0.unwrap();
1182 assert!(event.events.contains(SerialEventSet::MODEM_STATUS));
1183 assert!(
1184 ModemStatusFlags::from_bits_retain(REGS[UART_MSR as usize].load(Ordering::SeqCst))
1185 .intersection(ModemStatusFlags::DELTA_MASK)
1186 .is_empty()
1187 );
1188 }
1189
1190 #[test]
1191 fn irq_event_drains_rx_fifo_into_sink() {
1192 let (_guard, uart) = serial();
1193 let mut parts = started_parts(uart);
1194
1195 REGS[UART_IIR as usize].store(
1196 InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE.bits(),
1197 Ordering::SeqCst,
1198 );
1199 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1200 REGS[UART_RBR as usize].store(b'r', Ordering::SeqCst);
1201
1202 let (event, samples) = handle_irq(&mut parts.irq);
1203 let event = event.unwrap();
1204 assert!(event.events.contains(SerialEventSet::RX_DATA));
1205 assert_eq!(
1206 samples,
1207 [RxSample {
1208 byte: Some(b'r'),
1209 flag: RxFlag::Normal,
1210 overrun: false,
1211 }]
1212 );
1213 }
1214
1215 #[test]
1216 fn tx_irq_exposes_space_without_owning_a_software_fifo() {
1217 let (_guard, uart) = serial();
1218 let mut parts = started_parts(uart);
1219
1220 REGS[UART_IIR as usize].store(
1221 InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1222 Ordering::SeqCst,
1223 );
1224 REGS[UART_LSR as usize].store(
1225 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY.bits(),
1226 Ordering::SeqCst,
1227 );
1228
1229 let event = handle_irq(&mut parts.irq).0.unwrap();
1230 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1231 assert_eq!(parts.port.write_tx(b"ab"), 1);
1232 assert_eq!(REGS[UART_THR as usize].load(Ordering::SeqCst), b'a');
1233 }
1234
1235 #[test]
1236 fn irq_lsr_error_is_preserved_in_buffered_sample() {
1237 let (_guard, uart) = serial();
1238 let mut parts = started_parts(uart);
1239
1240 REGS[UART_IIR as usize].store(
1241 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1242 Ordering::SeqCst,
1243 );
1244 REGS[UART_LSR as usize].store(
1245 (LineStatusFlags::DATA_READY | LineStatusFlags::PARITY_ERROR).bits(),
1246 Ordering::SeqCst,
1247 );
1248 REGS[UART_RBR as usize].store(b'p', Ordering::SeqCst);
1249
1250 let (event, samples) = handle_irq(&mut parts.irq);
1251 let event = event.unwrap();
1252 assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1253 assert_eq!(
1254 samples,
1255 [RxSample {
1256 byte: Some(b'p'),
1257 flag: RxFlag::Parity,
1258 overrun: false,
1259 }]
1260 );
1261 }
1262
1263 #[test]
1264 fn port_rx_returns_current_byte_and_overrun_marker() {
1265 let (_guard, uart) = serial();
1266 let mut parts = started_parts(uart);
1267
1268 REGS[UART_IIR as usize].store(
1269 InterruptIdentificationFlags::RECEIVER_LINE_STATUS.bits(),
1270 Ordering::SeqCst,
1271 );
1272 REGS[UART_LSR as usize].store(
1273 (LineStatusFlags::DATA_READY | LineStatusFlags::OVERRUN_ERROR).bits(),
1274 Ordering::SeqCst,
1275 );
1276 REGS[UART_RBR as usize].store(b'S', Ordering::SeqCst);
1277
1278 assert_eq!(
1279 parts.port.read_rx(),
1280 Some(RxSample {
1281 byte: Some(b'S'),
1282 flag: RxFlag::Normal,
1283 overrun: true,
1284 })
1285 );
1286 }
1287
1288 #[test]
1289 fn irq_keeps_rx_source_enabled_after_draining_fifo() {
1290 let (_guard, uart) = serial();
1291 let mut parts = started_parts(uart);
1292 REGS[UART_IER as usize].store(UART_IER_RDI | UART_IER_RLSI, Ordering::SeqCst);
1293 REGS[UART_IIR as usize].store(UART_IIR_RDI, Ordering::SeqCst);
1294 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1295 REGS[UART_RBR as usize].store(b'q', Ordering::SeqCst);
1296
1297 let (event, samples) = handle_irq(&mut parts.irq);
1298 let event = event.unwrap();
1299
1300 assert!(event.events.contains(SerialEventSet::RX_DATA));
1301 assert!(!event.rearm.intersects(SerialEventSet::RX));
1302 assert_eq!(
1303 REGS[UART_IER as usize].load(Ordering::SeqCst),
1304 UART_IER_RDI | UART_IER_RLSI
1305 );
1306 assert_eq!(RBR_READS.load(Ordering::SeqCst), 1);
1307 assert_eq!(samples[0].byte, Some(b'q'));
1308 }
1309
1310 #[test]
1311 fn rearm_remasks_a_source_that_is_already_ready() {
1312 let (_guard, mut uart) = serial();
1313 uart.startup(&Config::new()).unwrap();
1314 REGS[UART_LSR as usize].store(LineStatusFlags::DATA_READY.bits(), Ordering::SeqCst);
1315
1316 let ready = uart.rearm(SerialEventSet::RX);
1317
1318 assert_eq!(ready, SerialEventSet::RX_DATA);
1319 assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), 0);
1320 }
1321
1322 #[test]
1323 fn unknown_irq_source_masks_all_and_reports_fault() {
1324 let (_guard, uart) = serial();
1325 let mut parts = started_parts(uart);
1326 REGS[UART_IER as usize].store(0xff, Ordering::SeqCst);
1327 REGS[UART_IIR as usize].store(0x08, Ordering::SeqCst);
1328
1329 let event = handle_irq(&mut parts.irq).0.unwrap();
1330
1331 assert!(event.events.contains(SerialEventSet::FAULT));
1332 assert_eq!(REGS[UART_IER as usize].load(Ordering::SeqCst), 0);
1333 assert_eq!(RBR_READS.load(Ordering::SeqCst), 0);
1334 assert_eq!(THR_WRITES.load(Ordering::SeqCst), 0);
1335 }
1336}