1use core::ptr::NonNull;
2
3use rdif_serial::{
4 Config, ConfigError, DataBits, IRQ_RX_BATCH_CAPACITY, IrqRxBatch, Parity, RxErrorFlags, RxFlag,
5 RxSample, SerialEventSet, SerialIrqEvent, SerialIrqReport, SerialParts, SplitUart, StopBits,
6 UartEmergencyTx, UartInfo, UartIrq, UartPort,
7};
8use tock_registers::{
9 LocalRegisterCopy, interfaces::*, register_bitfields, register_structs, registers::*,
10};
11
12use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
13
14const OPEN_BUSY_POLL_BUDGET: usize = 1 << 20;
15const EMERGENCY_TX_BUDGET: usize = 16;
16
17register_bitfields! [
18 u32,
19
20 UARTDR [
22 DATA OFFSET(0) NUMBITS(8) [],
23 FE OFFSET(8) NUMBITS(1) [],
24 PE OFFSET(9) NUMBITS(1) [],
25 BE OFFSET(10) NUMBITS(1) [],
26 OE OFFSET(11) NUMBITS(1) []
27 ],
28
29 UARTRSR_ECR [
31 FE OFFSET(0) NUMBITS(1) [],
32 PE OFFSET(1) NUMBITS(1) [],
33 BE OFFSET(2) NUMBITS(1) [],
34 OE OFFSET(3) NUMBITS(1) []
35 ],
36
37 UARTFR [
39 CTS OFFSET(0) NUMBITS(1) [],
40 DSR OFFSET(1) NUMBITS(1) [],
41 DCD OFFSET(2) NUMBITS(1) [],
42 BUSY OFFSET(3) NUMBITS(1) [],
43 RXFE OFFSET(4) NUMBITS(1) [],
44 TXFF OFFSET(5) NUMBITS(1) [],
45 RXFF OFFSET(6) NUMBITS(1) [],
46 TXFE OFFSET(7) NUMBITS(1) [],
47 RI OFFSET(8) NUMBITS(1) []
48 ],
49
50 UARTIBRD [
52 BAUD_DIVINT OFFSET(0) NUMBITS(16) []
53 ],
54
55 UARTFBRD [
57 BAUD_DIVFRAC OFFSET(0) NUMBITS(6) []
58 ],
59
60 UARTLCR_H [
62 BRK OFFSET(0) NUMBITS(1) [],
63 PEN OFFSET(1) NUMBITS(1) [],
64 EPS OFFSET(2) NUMBITS(1) [],
65 STP2 OFFSET(3) NUMBITS(1) [],
66 FEN OFFSET(4) NUMBITS(1) [],
67 WLEN OFFSET(5) NUMBITS(2) [
68 FiveBit = 0,
69 SixBit = 1,
70 SevenBit = 2,
71 EightBit = 3
72 ],
73 SPS OFFSET(7) NUMBITS(1) []
74 ],
75
76 UARTCR [
78 UARTEN OFFSET(0) NUMBITS(1) [],
79 SIREN OFFSET(1) NUMBITS(1) [],
80 SIRLP OFFSET(2) NUMBITS(1) [],
81 LBE OFFSET(7) NUMBITS(1) [],
82 TXE OFFSET(8) NUMBITS(1) [],
83 RXE OFFSET(9) NUMBITS(1) [],
84 DTR OFFSET(10) NUMBITS(1) [],
85 RTS OFFSET(11) NUMBITS(1) [],
86 OUT1 OFFSET(12) NUMBITS(1) [],
87 OUT2 OFFSET(13) NUMBITS(1) [],
88 RTSEN OFFSET(14) NUMBITS(1) [],
89 CTSEN OFFSET(15) NUMBITS(1) []
90 ],
91
92 UARTIFLS [
94 TXIFLSEL OFFSET(0) NUMBITS(3) [],
95 RXIFLSEL OFFSET(3) NUMBITS(3) []
96 ],
97
98 UARTIS [
100 RIM OFFSET(0) NUMBITS(1) [],
101 CTSM OFFSET(1) NUMBITS(1) [],
102 DCDM OFFSET(2) NUMBITS(1) [],
103 DSRM OFFSET(3) NUMBITS(1) [],
104 RX OFFSET(4) NUMBITS(1) [],
105 TX OFFSET(5) NUMBITS(1) [],
106 RT OFFSET(6) NUMBITS(1) [],
107 FE OFFSET(7) NUMBITS(1) [],
108 PE OFFSET(8) NUMBITS(1) [],
109 BE OFFSET(9) NUMBITS(1) [],
110 OE OFFSET(10) NUMBITS(1) []
111 ],
112
113 UARTDMACR [
115 RXDMAE OFFSET(0) NUMBITS(1) [],
116 TXDMAE OFFSET(1) NUMBITS(1) [],
117 DMAONERR OFFSET(2) NUMBITS(1) []
118 ]
119];
120
121register_structs! {
122 pub Pl011Registers {
123 (0x000 => uartdr: ReadWrite<u32, UARTDR::Register>), (0x004 => uartrsr_ecr: ReadWrite<u32, UARTRSR_ECR::Register>), (0x008 => _reserved1), (0x018 => uartfr: ReadOnly<u32, UARTFR::Register>), (0x01c => _reserved2), (0x020 => uartilpr: ReadWrite<u32>), (0x024 => uartibrd: ReadWrite<u32, UARTIBRD::Register>), (0x028 => uartfbrd: ReadWrite<u32, UARTFBRD::Register>), (0x02c => uartlcr_h: ReadWrite<u32, UARTLCR_H::Register>), (0x030 => uartcr: ReadWrite<u32, UARTCR::Register>), (0x034 => uartifls: ReadWrite<u32, UARTIFLS::Register>), (0x038 => uartimsc: ReadWrite<u32, UARTIS::Register>), (0x03c => uartris: ReadOnly<u32, UARTIS::Register>), (0x040 => uartmis: ReadOnly<u32, UARTIS::Register>), (0x044 => uarticr: WriteOnly<u32, UARTIS::Register>), (0x048 => uartdmacr: ReadWrite<u32, UARTDMACR::Register>), (0x04c => _reserved3), (0x1000 => @END),
141 }
142}
143
144unsafe impl Sync for Pl011Registers {}
146
147pub struct Pl011 {
149 base: Reg,
150 clock_freq: u32,
151 saved_rx_status: Pl011RxStatus,
152}
153
154#[derive(Clone, Copy)]
155struct Pl011ConfigSnapshot {
156 ilpr: u32,
157 ibrd: u32,
158 fbrd: u32,
159 lcr_h: u32,
160 cr: u32,
161 ifls: u32,
162 imsc: u32,
163 dmacr: u32,
164}
165
166impl Pl011ConfigSnapshot {
167 fn capture(registers: &Pl011Registers) -> Self {
168 Self {
169 ilpr: registers.uartilpr.get(),
170 ibrd: registers.uartibrd.get(),
171 fbrd: registers.uartfbrd.get(),
172 lcr_h: registers.uartlcr_h.get(),
173 cr: registers.uartcr.get(),
174 ifls: registers.uartifls.get(),
175 imsc: registers.uartimsc.get(),
176 dmacr: registers.uartdmacr.get(),
177 }
178 }
179
180 fn restore(self, registers: &Pl011Registers) {
181 registers.uartilpr.set(self.ilpr);
182 registers.uartibrd.set(self.ibrd);
183 registers.uartfbrd.set(self.fbrd);
184 registers.uartlcr_h.set(self.lcr_h);
185 registers.uartifls.set(self.ifls);
186 registers.uartimsc.set(self.imsc);
187 registers.uartdmacr.set(self.dmacr);
188 registers.uartcr.set(self.cr);
191 }
192}
193
194impl Pl011 {
195 pub fn new_no_clock(base: NonNull<u8>) -> Self {
200 let clock_freq = Self::detect_clock_frequency(base.as_ptr() as usize);
202 Self::new(base, clock_freq)
203 }
204
205 pub fn new(base: NonNull<u8>, clock_freq: u32) -> Self {
206 let base = Reg(base.cast());
207
208 Self {
209 base,
210 clock_freq,
211 saved_rx_status: Pl011RxStatus::empty(),
212 }
213 }
214
215 fn registers(&self) -> &Pl011Registers {
216 unsafe { &*self.base.0.as_ptr() }
217 }
218
219 fn wait_until_idle(&self) -> bool {
220 for _ in 0..OPEN_BUSY_POLL_BUDGET {
221 if !self.registers().uartfr.is_set(UARTFR::BUSY) {
222 return true;
223 }
224 core::hint::spin_loop();
225 }
226 false
227 }
228
229 fn current_baudrate(&self) -> u32 {
230 let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
231 let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
232 let divisor = ibrd * 64 + fbrd;
233 if divisor == 0 {
234 0
235 } else {
236 self.clock_freq * 64 / (16 * divisor)
237 }
238 }
239
240 fn detect_clock_frequency(base: usize) -> u32 {
242 let registers = unsafe { &*(base as *const Pl011Registers) };
244
245 use tock_registers::interfaces::Readable;
246 let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
247
248 if ibrd > 0 && ibrd <= 0xFFFF {
250 let estimated_clock = 16 * ibrd * 115200;
253
254 if (1_000_000..=100_000_000).contains(&estimated_clock) {
256 return estimated_clock;
257 }
258 }
259
260 24_000_000
262 }
263
264 fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
266 let scaled_baudrate = baudrate
272 .checked_mul(16)
273 .filter(|scaled| *scaled != 0)
274 .ok_or(ConfigError::InvalidBaudrate)?;
275 let bauddiv = self.clock_freq / scaled_baudrate;
276 let remainder = self.clock_freq % scaled_baudrate;
277 let fbrd = (remainder * 64 + scaled_baudrate / 2) / scaled_baudrate;
278
279 if bauddiv == 0 || bauddiv > 0xFFFF {
280 return Err(ConfigError::InvalidBaudrate);
281 }
282
283 self.registers()
284 .uartibrd
285 .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
286 self.registers()
287 .uartfbrd
288 .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
289
290 Ok(())
291 }
292
293 fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
294 let wlen = match bits {
295 DataBits::Five => UARTLCR_H::WLEN::FiveBit,
296 DataBits::Six => UARTLCR_H::WLEN::SixBit,
297 DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
298 DataBits::Eight => UARTLCR_H::WLEN::EightBit,
299 };
300
301 self.registers().uartlcr_h.modify(wlen);
302 Ok(())
303 }
304
305 fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
306 match bits {
307 StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
308 StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
309 }
310
311 Ok(())
312 }
313
314 fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
315 match parity {
316 Parity::None => {
317 self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
319 }
320 Parity::Odd => {
321 self.registers()
323 .uartlcr_h
324 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
325 }
326 Parity::Even => {
327 self.registers()
329 .uartlcr_h
330 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
331 }
332 Parity::Mark => {
333 self.registers()
335 .uartlcr_h
336 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
337 }
338 Parity::Space => {
339 self.registers()
341 .uartlcr_h
342 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
343 }
344 }
345
346 Ok(())
347 }
348
349 pub fn open(&mut self) -> Result<(), ConfigError> {
354 let snapshot = Pl011ConfigSnapshot::capture(self.registers());
355
356 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
358
359 if !self.wait_until_idle() {
361 snapshot.restore(self.registers());
362 return Err(ConfigError::Timeout);
363 }
364
365 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
367
368 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
370
371 #[cfg(debug_assertions)]
373 {
374 let ifls = self.registers().uartifls.get();
375 let lcr_h = self.registers().uartlcr_h.get();
376 log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
377 log::debug!(" FIFO enabled: {}", lcr_h & (1 << 4) != 0);
378 log::debug!(" RX trigger level: 1/8");
379 log::debug!(" TX trigger level: 1/2");
380 }
381 self.registers().uartimsc.set(0); self.registers()
384 .uartcr
385 .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
386 Ok(())
387 }
388
389 pub fn set_irq_mask(&mut self, events: SerialEventSet) {
390 self.registers().uartimsc.set(imsc_for_events(events));
391 }
392
393 pub fn get_irq_mask(&self) -> SerialEventSet {
394 let imsc = self.registers().uartimsc.extract();
395 let mut events = SerialEventSet::empty();
396
397 if imsc.is_set(UARTIS::RX)
398 || imsc.is_set(UARTIS::RT)
399 || imsc.is_set(UARTIS::FE)
400 || imsc.is_set(UARTIS::PE)
401 || imsc.is_set(UARTIS::BE)
402 || imsc.is_set(UARTIS::OE)
403 {
404 events |= SerialEventSet::RX;
405 }
406 if imsc.is_set(UARTIS::TX) {
407 events |= SerialEventSet::TX_SPACE;
408 }
409
410 events
411 }
412
413 pub fn pending(&mut self, direction: SerialDirection) -> bool {
414 match direction {
415 SerialDirection::Input => !self.registers().uartfr.is_set(UARTFR::RXFE),
416 SerialDirection::Output => !self.registers().uartfr.is_set(UARTFR::TXFF),
417 }
418 }
419
420 pub fn poll_status(&mut self) -> SerialEvent {
421 let mut event = SerialEvent::empty();
422 let fr = self.registers().uartfr.extract();
423 if !fr.is_set(UARTFR::RXFE) {
424 event |= SerialEvent::RX_READY;
425 }
426 if !fr.is_set(UARTFR::TXFF) {
427 event |= SerialEvent::TX_READY;
428 }
429
430 let status =
431 self.saved_rx_status | Pl011RxStatus::from_rsr(self.registers().uartrsr_ecr.extract());
432 if status.intersects(Pl011RxStatus::FRAMING | Pl011RxStatus::PARITY | Pl011RxStatus::BREAK)
433 {
434 event |= SerialEvent::RX_ERROR;
435 }
436 if status.contains(Pl011RxStatus::OVERRUN) {
437 event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
438 }
439
440 event
441 }
442
443 pub fn try_write(&mut self, bytes: &[u8]) -> usize {
444 let mut written = 0;
445 for &byte in bytes {
446 let status = self.poll_status();
447 if !status.tx_ready() {
448 break;
449 }
450 self.write_byte(byte);
451 written += 1;
452 }
453 written
454 }
455
456 pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
457 let mut count = 0;
458 for byte in bytes.iter_mut() {
459 let status = self.poll_status();
460 if !status.rx_ready() && !status.rx_error() {
461 break;
462 }
463 match self.read_byte(status) {
464 Some(Ok(b)) => {
465 *byte = b;
466 }
467 Some(Err(TransferError::Overrun(b))) => {
468 *byte = b;
469 count += 1;
470 return Err(TransBytesError {
471 bytes_transferred: count,
472 kind: TransferError::Overrun(b),
473 });
474 }
475 Some(Err(e)) => {
476 return Err(TransBytesError {
477 bytes_transferred: count,
478 kind: e,
479 });
480 }
481 None => break,
482 }
483 count += 1;
484 }
485 Ok(count)
486 }
487
488 pub fn write_byte(&mut self, byte: u8) {
489 self.registers().uartdr.set(byte as _);
490 }
491
492 pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
493 if !status.rx_ready() && !status.rx_error() {
494 return None;
495 }
496
497 let sample = self.read_rx()?;
498 if sample.overrun {
499 return Some(Err(TransferError::Overrun(sample.byte.unwrap_or(0))));
500 }
501 match sample.flag {
502 RxFlag::Normal => sample.byte.map(Ok),
503 RxFlag::Break => Some(Err(TransferError::Break)),
504 RxFlag::Parity => Some(Err(TransferError::Parity)),
505 RxFlag::Framing => Some(Err(TransferError::Framing)),
506 }
507 }
508
509 pub fn read_rx(&mut self) -> Option<RxSample> {
510 let base = self.base;
511 let registers = unsafe { &*base.0.as_ptr() };
514 read_rx_sample(registers, &mut self.saved_rx_status)
515 }
516}
517
518fn read_rx_sample(
519 registers: &Pl011Registers,
520 saved_status: &mut Pl011RxStatus,
521) -> Option<RxSample> {
522 if registers.uartfr.is_set(UARTFR::RXFE) {
523 *saved_status |= Pl011RxStatus::from_rsr(registers.uartrsr_ecr.extract());
524 return saved_status.take_status_sample();
525 }
526
527 let dr = registers.uartdr.extract();
528 let data = dr.read(UARTDR::DATA) as u8;
529 let status = Pl011RxStatus::from_data(dr);
530 if !status.is_empty() {
531 saved_status.remove(status);
532 }
533
534 Some(RxSample {
535 byte: Some(data),
536 flag: status.flag(),
537 overrun: status.contains(Pl011RxStatus::OVERRUN),
538 })
539}
540
541fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
542 let mut errors = match sample.flag {
543 RxFlag::Normal => RxErrorFlags::empty(),
544 RxFlag::Break => RxErrorFlags::BREAK,
545 RxFlag::Parity => RxErrorFlags::PARITY,
546 RxFlag::Framing => RxErrorFlags::FRAMING,
547 };
548 if sample.overrun {
549 errors |= RxErrorFlags::OVERRUN;
550 }
551 errors
552}
553
554bitflags::bitflags! {
555 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
556 struct Pl011RxStatus: u32 {
557 const FRAMING = 1 << 0;
558 const PARITY = 1 << 1;
559 const BREAK = 1 << 2;
560 const OVERRUN = 1 << 3;
561 }
562}
563
564impl Pl011RxStatus {
565 fn to_irq_errors(self) -> RxErrorFlags {
566 let mut errors = RxErrorFlags::empty();
567 if self.contains(Self::BREAK) {
568 errors |= RxErrorFlags::BREAK;
569 }
570 if self.contains(Self::PARITY) {
571 errors |= RxErrorFlags::PARITY;
572 }
573 if self.contains(Self::FRAMING) {
574 errors |= RxErrorFlags::FRAMING;
575 }
576 if self.contains(Self::OVERRUN) {
577 errors |= RxErrorFlags::OVERRUN;
578 }
579 errors
580 }
581
582 fn from_data(dr: LocalRegisterCopy<u32, UARTDR::Register>) -> Self {
583 let mut status = Self::empty();
584 if dr.is_set(UARTDR::FE) {
585 status |= Self::FRAMING;
586 }
587 if dr.is_set(UARTDR::PE) {
588 status |= Self::PARITY;
589 }
590 if dr.is_set(UARTDR::BE) {
591 status |= Self::BREAK;
592 }
593 if dr.is_set(UARTDR::OE) {
594 status |= Self::OVERRUN;
595 }
596 status
597 }
598
599 fn from_irq_status(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> Self {
600 let mut status = Self::empty();
601 if mis.is_set(UARTIS::FE) {
602 status |= Self::FRAMING;
603 }
604 if mis.is_set(UARTIS::PE) {
605 status |= Self::PARITY;
606 }
607 if mis.is_set(UARTIS::BE) {
608 status |= Self::BREAK;
609 }
610 if mis.is_set(UARTIS::OE) {
611 status |= Self::OVERRUN;
612 }
613 status
614 }
615
616 fn from_rsr(rsr: LocalRegisterCopy<u32, UARTRSR_ECR::Register>) -> Self {
617 let mut status = Self::empty();
618 if rsr.is_set(UARTRSR_ECR::FE) {
619 status |= Self::FRAMING;
620 }
621 if rsr.is_set(UARTRSR_ECR::PE) {
622 status |= Self::PARITY;
623 }
624 if rsr.is_set(UARTRSR_ECR::BE) {
625 status |= Self::BREAK;
626 }
627 if rsr.is_set(UARTRSR_ECR::OE) {
628 status |= Self::OVERRUN;
629 }
630 status
631 }
632
633 fn flag(self) -> RxFlag {
634 if self.contains(Self::BREAK) {
635 RxFlag::Break
636 } else if self.contains(Self::PARITY) {
637 RxFlag::Parity
638 } else if self.contains(Self::FRAMING) {
639 RxFlag::Framing
640 } else {
641 RxFlag::Normal
642 }
643 }
644
645 fn take_status_sample(&mut self) -> Option<RxSample> {
646 if self.is_empty() {
647 return None;
648 }
649
650 let status = *self;
651 *self = Self::empty();
652 Some(RxSample {
653 byte: None,
654 flag: status.flag(),
655 overrun: status.contains(Self::OVERRUN),
656 })
657 }
658}
659
660#[derive(Clone, Copy, PartialEq, Eq)]
661struct Reg(NonNull<Pl011Registers>);
662
663unsafe impl Send for Reg {}
664unsafe impl Sync for Reg {}
665
666pub struct Pl011Irq {
668 base: Reg,
669 saved_rx_status: Pl011RxStatus,
670}
671
672pub struct Pl011EmergencyTx {
674 base: Reg,
675}
676
677impl Pl011EmergencyTx {
678 fn registers(&self) -> &Pl011Registers {
679 unsafe { &*self.base.0.as_ptr() }
682 }
683
684 fn mask_interrupts(&self) {
685 self.registers().uartimsc.set(0);
686 let _masked = self.registers().uartimsc.get();
688 }
689}
690
691impl UartEmergencyTx for Pl011EmergencyTx {
692 unsafe fn mask_interrupts_unlocked(&self) {
693 self.mask_interrupts();
694 }
695
696 unsafe fn try_write_unlocked(&self, bytes: &[u8]) -> usize {
697 let mut written = 0;
698 for &byte in bytes.iter().take(EMERGENCY_TX_BUDGET) {
699 if self.registers().uartfr.is_set(UARTFR::TXFF) {
700 break;
701 }
702 self.registers().uartdr.set(byte as u32);
703 written += 1;
704 }
705 written
706 }
707}
708
709impl Pl011Irq {
710 fn registers(&self) -> &Pl011Registers {
711 unsafe { &*self.base.0.as_ptr() }
714 }
715}
716
717impl UartIrq for Pl011Irq {
718 fn mask(&mut self, sources: SerialEventSet) {
719 let enabled = self.registers().uartimsc.get();
720 self.registers()
721 .uartimsc
722 .set(enabled & !imsc_for_events(sources));
723 }
724
725 fn handle(&mut self) -> Option<SerialIrqReport> {
726 let mis = self.registers().uartmis.extract();
727 let active = mis.get();
728 if active == 0 {
729 return None;
730 }
731
732 let mut events = events_from_mis(mis);
733 let mut rx = IrqRxBatch::new();
734 if active & !0x7ff != 0 {
735 events |= SerialEventSet::FAULT;
736 }
737 let mut rx_errors = rx_errors_from_mis(mis);
738 if events.intersects(SerialEventSet::RX) {
739 let base = self.base;
740 let registers = unsafe { &*base.0.as_ptr() };
743 for _ in 0..IRQ_RX_BATCH_CAPACITY {
744 let Some(sample) = read_rx_sample(registers, &mut self.saved_rx_status) else {
745 break;
746 };
747 rx_errors |= rx_errors_from_sample(sample);
748 rx.try_push(sample)
749 .expect("the fixed PL011 IRQ loop cannot overflow its RX batch");
750 }
751 }
752
753 let mut rearm = events & SerialEventSet::TX_SPACE;
754 if rx.len() == IRQ_RX_BATCH_CAPACITY || rx_errors.contains(RxErrorFlags::OVERRUN) {
755 rearm |= SerialEventSet::RX;
756 }
757 if events.contains(SerialEventSet::FAULT) {
758 self.registers().uartimsc.set(0);
759 } else if !rearm.is_empty() {
760 self.mask(rearm);
761 }
762 self.registers().uarticr.set(active);
763
764 Some(SerialIrqReport::new(
765 SerialIrqEvent {
766 events,
767 rx_errors,
768 rearm,
769 },
770 rx,
771 ))
772 }
773}
774
775impl UartPort for Pl011 {
776 fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
777 let snapshot = Pl011ConfigSnapshot::capture(self.registers());
778 if let Err(error) = self.open().and_then(|()| self.set_config(config)) {
779 snapshot.restore(self.registers());
780 return Err(error);
781 }
782 self.mask_all();
783 Ok(())
784 }
785
786 fn shutdown(&mut self) {
787 self.registers().uartimsc.set(0);
788 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
789 }
790
791 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
792 let snapshot = Pl011ConfigSnapshot::capture(self.registers());
793 let result = (|| {
794 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
795 if !self.wait_until_idle() {
796 return Err(ConfigError::Timeout);
797 }
798
799 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
800 if let Some(baudrate) = config.baudrate {
801 self.set_baudrate_internal(baudrate)?;
802 }
803 if let Some(data_bits) = config.data_bits {
804 self.set_data_bits_internal(data_bits)?;
805 }
806 if let Some(stop_bits) = config.stop_bits {
807 self.set_stop_bits_internal(stop_bits)?;
808 }
809 if let Some(parity) = config.parity {
810 self.set_parity_internal(parity)?;
811 }
812 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
813 self.registers().uartcr.set(snapshot.cr);
814 Ok(())
815 })();
816
817 if result.is_err() {
818 snapshot.restore(self.registers());
819 }
820 result
821 }
822
823 fn read_rx(&mut self) -> Option<RxSample> {
824 Pl011::read_rx(self)
825 }
826
827 fn discard_rx(&mut self) {
828 while !self.registers().uartfr.is_set(UARTFR::RXFE) {
829 let _ = self.registers().uartdr.get();
830 }
831 self.saved_rx_status = Pl011RxStatus::empty();
832 self.registers().uartrsr_ecr.set(0);
833 self.registers()
834 .uarticr
835 .set(imsc_for_events(SerialEventSet::RX));
836 }
837
838 fn write_tx(&mut self, bytes: &[u8]) -> usize {
839 let mut written = 0;
840 for &byte in bytes {
841 if self.registers().uartfr.is_set(UARTFR::TXFF) {
842 break;
843 }
844 self.registers().uartdr.set(byte as u32);
845 written += 1;
846 }
847 written
848 }
849
850 fn discard_tx(&mut self) -> bool {
851 false
852 }
853
854 fn tx_idle(&mut self) -> bool {
855 let fr = self.registers().uartfr.extract();
856 !fr.is_set(UARTFR::BUSY) && !fr.is_set(UARTFR::TXFF)
857 }
858
859 fn mask(&mut self, sources: SerialEventSet) {
860 let enabled = self.registers().uartimsc.get();
861 self.registers()
862 .uartimsc
863 .set(enabled & !imsc_for_events(sources));
864 }
865
866 fn mask_all(&mut self) {
867 self.registers().uartimsc.set(0);
868 }
869
870 fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
871 let enabled = self.registers().uartimsc.get() | imsc_for_events(sources);
872 self.registers().uartimsc.set(enabled);
873
874 let fr = self.registers().uartfr.extract();
875 let rsr = self.registers().uartrsr_ecr.extract();
876 let mut ready = SerialEventSet::empty();
877 if sources.intersects(SerialEventSet::RX) && !fr.is_set(UARTFR::RXFE) {
878 ready |= SerialEventSet::RX_DATA;
879 }
880 if sources.contains(SerialEventSet::RX_STATUS) && !Pl011RxStatus::from_rsr(rsr).is_empty() {
881 ready |= SerialEventSet::RX_STATUS;
882 }
883 if sources.contains(SerialEventSet::TX_SPACE) && !fr.is_set(UARTFR::TXFF) {
884 ready |= SerialEventSet::TX_SPACE;
885 }
886 if !ready.is_empty() {
887 self.registers()
888 .uartimsc
889 .set(enabled & !imsc_for_events(ready));
890 }
891 ready
892 }
893}
894
895impl SplitUart for Pl011 {
896 type Control = Self;
897 type Irq = Pl011Irq;
898 type EmergencyTx = Pl011EmergencyTx;
899
900 fn runtime_info(&self) -> UartInfo {
901 UartInfo {
902 name: "PL011 UART",
903 register_base: self.base.0.as_ptr() as usize,
904 initial_baudrate: self.current_baudrate(),
905 }
906 }
907
908 fn split(self) -> SerialParts<Self::Control, Self::Irq, Self::EmergencyTx> {
909 let irq = Pl011Irq {
910 base: self.base,
911 saved_rx_status: Pl011RxStatus::empty(),
912 };
913 let emergency_tx = Pl011EmergencyTx { base: self.base };
914 SerialParts::new(self, irq, emergency_tx)
915 }
916}
917
918impl PollingUart for Pl011 {
919 fn poll_status(&mut self) -> SerialEvent {
920 Pl011::poll_status(self)
921 }
922
923 fn write_byte(&mut self, byte: u8) {
924 Pl011::write_byte(self, byte);
925 }
926
927 fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
928 Pl011::read_byte(self, status)
929 }
930}
931
932fn events_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> SerialEventSet {
933 let mut events = SerialEventSet::empty();
934 if mis.is_set(UARTIS::RX) {
935 events |= SerialEventSet::RX_DATA;
936 }
937 if mis.is_set(UARTIS::RT) {
938 events |= SerialEventSet::RX_TIMEOUT;
939 }
940 if mis.is_set(UARTIS::FE)
941 || mis.is_set(UARTIS::PE)
942 || mis.is_set(UARTIS::BE)
943 || mis.is_set(UARTIS::OE)
944 {
945 events |= SerialEventSet::RX_STATUS;
946 }
947 if mis.is_set(UARTIS::TX) {
948 events |= SerialEventSet::TX_SPACE;
949 }
950 if mis.is_set(UARTIS::CTSM)
951 || mis.is_set(UARTIS::DSRM)
952 || mis.is_set(UARTIS::DCDM)
953 || mis.is_set(UARTIS::RIM)
954 {
955 events |= SerialEventSet::MODEM_STATUS;
956 }
957 events
958}
959
960fn rx_errors_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> RxErrorFlags {
961 Pl011RxStatus::from_irq_status(mis).to_irq_errors()
962}
963
964fn imsc_for_events(events: SerialEventSet) -> u32 {
965 let mut imsc = 0;
966 if events.intersects(SerialEventSet::RX) {
967 imsc |= UARTIS::RX::SET.value
968 | UARTIS::RT::SET.value
969 | UARTIS::FE::SET.value
970 | UARTIS::PE::SET.value
971 | UARTIS::BE::SET.value
972 | UARTIS::OE::SET.value;
973 }
974 if events.contains(SerialEventSet::TX_SPACE) {
975 imsc |= UARTIS::TX::SET.value;
976 }
977 if events.contains(SerialEventSet::MODEM_STATUS) {
978 imsc |= UARTIS::RIM::SET.value
979 | UARTIS::CTSM::SET.value
980 | UARTIS::DCDM::SET.value
981 | UARTIS::DSRM::SET.value;
982 }
983 imsc
984}
985
986impl Pl011 {
988 pub fn enable_fifo(&self, enable: bool) {
990 if enable {
991 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
992 } else {
993 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
994 }
995 }
996
997 pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
999 let rx_iflsel = match rx_level {
1007 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
1013
1014 let tx_iflsel = match tx_level {
1015 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
1021
1022 self.registers()
1023 .uartifls
1024 .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
1025 }
1026}
1027
1028#[cfg(test)]
1031mod tests {
1032 use core::ptr::NonNull;
1033 use std::{boxed::Box, vec::Vec};
1034
1035 use rdif_serial::UartRegisterGate;
1036
1037 use super::*;
1038
1039 trait AssertOpenTimeout {
1042 fn assert_timeout(self);
1043 }
1044
1045 impl AssertOpenTimeout for () {
1046 fn assert_timeout(self) {
1047 panic!("unbounded PL011 open returned without reporting a timeout");
1048 }
1049 }
1050
1051 impl AssertOpenTimeout for Result<(), ConfigError> {
1052 fn assert_timeout(self) {
1053 assert_eq!(self, Err(ConfigError::Timeout));
1054 }
1055 }
1056
1057 fn handle_irq(irq: &mut impl UartIrq) -> (Option<SerialIrqEvent>, Vec<RxSample>) {
1058 let Some(report) = irq.handle() else {
1059 return (None, Vec::new());
1060 };
1061 (Some(report.event), report.rx.as_slice().to_vec())
1062 }
1063
1064 fn pl011_with_registers() -> (Box<Pl011Registers>, Pl011) {
1065 let mut regs = Box::new(unsafe { core::mem::zeroed::<Pl011Registers>() });
1066 let ptr = NonNull::from(regs.as_mut()).cast::<u8>();
1067 let uart = Pl011::new(ptr, 24_000_000);
1068 (regs, uart)
1069 }
1070
1071 fn pl011_with_overrun_data() -> (Box<Pl011Registers>, Pl011) {
1072 let (regs, uart) = pl011_with_registers();
1073 regs.uartdr
1074 .set((UARTDR::DATA.val(0xab) + UARTDR::OE::SET).into());
1075 (regs, uart)
1076 }
1077
1078 fn write_test_reg(regs: &mut Pl011Registers, offset: usize, value: u32) {
1079 unsafe {
1080 (regs as *mut Pl011Registers)
1081 .cast::<u32>()
1082 .add(offset / core::mem::size_of::<u32>())
1083 .write_volatile(value);
1084 }
1085 }
1086
1087 fn read_test_reg(regs: &Pl011Registers, offset: usize) -> u32 {
1088 unsafe {
1089 (regs as *const Pl011Registers)
1090 .cast::<u32>()
1091 .add(offset / core::mem::size_of::<u32>())
1092 .read_volatile()
1093 }
1094 }
1095
1096 const CONFIG_REGISTER_OFFSETS: [usize; 8] =
1097 [0x020, 0x024, 0x028, 0x02c, 0x030, 0x034, 0x038, 0x048];
1098
1099 fn config_register_snapshot(regs: &Pl011Registers) -> [u32; 8] {
1100 CONFIG_REGISTER_OFFSETS.map(|offset| read_test_reg(regs, offset))
1101 }
1102
1103 fn seed_config_registers(regs: &mut Pl011Registers) {
1104 for (index, offset) in CONFIG_REGISTER_OFFSETS.into_iter().enumerate() {
1105 write_test_reg(regs, offset, 0x10 + index as u32);
1106 }
1107 }
1108
1109 fn started_parts(uart: Pl011) -> SerialParts<Pl011, Pl011Irq, Pl011EmergencyTx> {
1110 let mut parts = uart.split();
1111 parts.control.startup(&Config::new()).unwrap();
1112 parts
1113 }
1114
1115 #[test]
1116 fn early_console_open_has_a_bounded_busy_failure() {
1117 let (mut regs, mut uart) = pl011_with_registers();
1118 let original_uartcr = (UARTCR::UARTEN::SET
1119 + UARTCR::SIREN::SET
1120 + UARTCR::LBE::SET
1121 + UARTCR::TXE::SET
1122 + UARTCR::DTR::SET
1123 + UARTCR::OUT2::SET
1124 + UARTCR::CTSEN::SET)
1125 .value;
1126 write_test_reg(&mut regs, 0x018, UARTFR::BUSY::SET.value);
1127 write_test_reg(&mut regs, 0x030, original_uartcr);
1128
1129 uart.open().assert_timeout();
1130
1131 assert_eq!(read_test_reg(®s, 0x030), original_uartcr);
1132 }
1133
1134 #[test]
1135 fn raw_rx_reports_overrun_instead_of_swallowing_it() {
1136 let (_regs, mut uart) = pl011_with_overrun_data();
1137
1138 let mut buf = [0];
1139 let err = uart
1140 .try_read(&mut buf)
1141 .expect_err("overrun must be reported to the caller");
1142
1143 assert_eq!(buf[0], 0xab);
1144 assert_eq!(err.bytes_transferred, 1);
1145 assert_eq!(err.kind, TransferError::Overrun(0xab));
1146 }
1147
1148 #[test]
1149 fn raw_rx_sample_reports_overrun_instead_of_swallowing_it() {
1150 let (mut regs, uart) = pl011_with_overrun_data();
1151 let mut parts = uart.split();
1152
1153 write_test_reg(&mut regs, 0x040, UARTIS::OE::SET.value);
1154 let (event, samples) = handle_irq(&mut parts.irq);
1155 let event = event.unwrap();
1156 assert!(event.events.contains(SerialEventSet::RX_STATUS));
1157 assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1158 assert_eq!(
1159 samples.len(),
1160 IRQ_RX_BATCH_CAPACITY,
1161 "the hard IRQ must enforce its RX budget"
1162 );
1163 let sample = samples[0];
1164 assert_eq!(sample.byte, Some(0xab));
1165 assert_eq!(sample.flag, RxFlag::Normal);
1166 assert!(sample.overrun);
1167 }
1168
1169 #[test]
1170 fn rx_irq_masks_source_after_bounded_fifo_drain() {
1171 let (mut regs, uart) = pl011_with_registers();
1172 let mut irq = uart.split().irq;
1173 let rx_mask = imsc_for_events(SerialEventSet::RX);
1174 write_test_reg(&mut regs, 0x038, rx_mask);
1175 write_test_reg(&mut regs, 0x040, UARTIS::RX::SET.value);
1176 write_test_reg(&mut regs, 0x018, 0);
1177 regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1178
1179 let (event, samples) = handle_irq(&mut irq);
1180 let event = event.unwrap();
1181
1182 assert!(event.events.contains(SerialEventSet::RX_DATA));
1183 assert!(event.rearm.contains(SerialEventSet::RX));
1184 assert_eq!(samples.len(), IRQ_RX_BATCH_CAPACITY);
1185 assert_eq!(read_test_reg(®s, 0x038) & rx_mask, 0);
1186 }
1187
1188 #[test]
1189 fn irq_status_without_rx_byte_is_preserved_after_irq_ack() {
1190 let (mut regs, uart) = pl011_with_registers();
1191 let mut parts = uart.split();
1192
1193 write_test_reg(
1194 &mut regs,
1195 0x040,
1196 UARTIS::OE::SET.value | UARTIS::PE::SET.value,
1197 );
1198 write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1199
1200 let event = handle_irq(&mut parts.irq).0.unwrap();
1201 assert!(event.events.contains(SerialEventSet::RX_STATUS));
1202 assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1203 assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1204 assert!(parts.control.read_rx().is_none());
1205 }
1206
1207 #[test]
1208 fn tx_irq_exposes_space_without_owning_a_software_fifo() {
1209 let (mut regs, uart) = pl011_with_registers();
1210 let mut parts = started_parts(uart);
1211
1212 write_test_reg(&mut regs, 0x018, 0);
1213 write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1214 let event = handle_irq(&mut parts.irq).0.unwrap();
1215 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1216 assert_eq!(parts.control.write_tx(b"x"), 1);
1217 assert_eq!(regs.uartdr.get() as u8, b'x');
1218 }
1219
1220 #[test]
1221 fn emergency_tx_returns_immediately_when_the_fifo_is_full() {
1222 let (mut regs, uart) = pl011_with_registers();
1223 let parts = uart.split();
1224 let gate = UartRegisterGate::new(parts.emergency_tx);
1225 let access = gate.try_begin_emergency().unwrap();
1226 write_test_reg(&mut regs, 0x018, UARTFR::TXFF::SET.value);
1227
1228 assert_eq!(access.try_write(b"x"), 0);
1229
1230 write_test_reg(&mut regs, 0x018, 0);
1231 assert_eq!(access.try_write(b"x"), 1);
1232 assert_eq!(regs.uartdr.get() as u8, b'x');
1233 }
1234
1235 #[test]
1236 fn emergency_tx_has_a_fixed_write_budget() {
1237 let (mut regs, uart) = pl011_with_registers();
1238 let parts = uart.split();
1239 write_test_reg(&mut regs, 0x018, 0);
1240 let bytes = [b'x'; EMERGENCY_TX_BUDGET + 1];
1241 let gate = UartRegisterGate::new(parts.emergency_tx);
1242 let access = gate.try_begin_emergency().unwrap();
1243
1244 assert_eq!(access.try_write(&bytes), EMERGENCY_TX_BUDGET);
1245 }
1246
1247 #[test]
1248 fn emergency_takeover_leaves_device_interrupts_masked() {
1249 let (mut regs, uart) = pl011_with_registers();
1250 let gate = UartRegisterGate::new(uart.split().emergency_tx);
1251 let enabled = UARTIS::RX::SET.value | UARTIS::TX::SET.value;
1252 write_test_reg(&mut regs, 0x038, enabled);
1253
1254 let access = gate.try_begin_emergency().unwrap();
1255 assert_eq!(
1256 read_test_reg(®s, 0x038),
1257 0,
1258 "a gate-busy IRQ must observe a device-masked emergency transaction"
1259 );
1260 assert_eq!(access.try_write(b"x"), 1);
1261 assert_eq!(
1262 read_test_reg(®s, 0x038),
1263 0,
1264 "terminal emergency ownership must not rearm the UART source"
1265 );
1266 }
1267
1268 #[test]
1269 fn discard_rx_clears_saved_status_without_touching_tx_data() {
1270 let (mut regs, mut uart) = pl011_with_registers();
1271 uart.saved_rx_status = Pl011RxStatus::PARITY;
1272 regs.uartdr.set(UARTDR::DATA.val(b'x' as u32).into());
1273 write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1274
1275 UartPort::discard_rx(&mut uart);
1276
1277 assert!(uart.saved_rx_status.is_empty());
1278 assert_eq!(regs.uartdr.get() as u8, b'x');
1279 assert_eq!(
1280 read_test_reg(®s, 0x044) & imsc_for_events(SerialEventSet::RX),
1281 imsc_for_events(SerialEventSet::RX),
1282 );
1283 }
1284
1285 #[test]
1286 fn discard_tx_reports_unsupported_without_touching_rx_data() {
1287 let (mut regs, mut uart) = pl011_with_registers();
1288 regs.uartlcr_h.modify(UARTLCR_H::FEN::SET);
1289 regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1290 write_test_reg(&mut regs, 0x018, 0);
1291 let lcr_h = regs.uartlcr_h.get();
1292
1293 assert!(!UartPort::discard_tx(&mut uart));
1294 assert_eq!(regs.uartlcr_h.get(), lcr_h);
1295 assert_eq!(uart.read_rx().unwrap().byte, Some(b'r'));
1296 }
1297
1298 #[test]
1299 fn tx_irq_endpoint_acknowledges_tx_interrupt() {
1300 let (mut regs, uart) = pl011_with_registers();
1301 let mut irq = uart.split().irq;
1302
1303 write_test_reg(&mut regs, 0x000, 0x5a);
1304 write_test_reg(&mut regs, 0x038, UARTIS::TX::SET.value);
1305 write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1306 let event = handle_irq(&mut irq).0.unwrap();
1307
1308 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1309 assert_eq!(event.rearm, SerialEventSet::TX_SPACE);
1310 assert_eq!(
1311 read_test_reg(®s, 0x044) & UARTIS::TX::SET.value,
1312 UARTIS::TX::SET.value
1313 );
1314 assert_eq!(read_test_reg(®s, 0x038) & UARTIS::TX::SET.value, 0);
1315 assert_eq!(read_test_reg(®s, 0x000), 0x5a);
1316 }
1317
1318 #[test]
1319 fn overrun_irq_masks_receive_sources_until_worker_rearm() {
1320 let (mut regs, uart) = pl011_with_registers();
1321 let mut irq = uart.split().irq;
1322 let rx_sources = imsc_for_events(SerialEventSet::RX);
1323 write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1324 write_test_reg(&mut regs, 0x038, rx_sources);
1325 write_test_reg(&mut regs, 0x040, UARTIS::OE::SET.value);
1326
1327 let report = irq.handle().expect("PL011 overrun interrupt report");
1328
1329 assert!(report.event.rx_errors.contains(RxErrorFlags::OVERRUN));
1330 assert!(report.event.rearm.contains(SerialEventSet::RX));
1331 assert_eq!(read_test_reg(®s, 0x038) & rx_sources, 0);
1332 }
1333
1334 #[test]
1335 fn drained_rx_irq_keeps_receive_sources_enabled() {
1336 let (mut regs, uart) = pl011_with_registers();
1337 let mut irq = uart.split().irq;
1338 let rx_sources = imsc_for_events(SerialEventSet::RX);
1339 write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1340 write_test_reg(&mut regs, 0x038, rx_sources);
1341 write_test_reg(&mut regs, 0x040, UARTIS::RX::SET.value);
1342
1343 let report = irq.handle().expect("PL011 drained RX interrupt report");
1344
1345 assert!(report.rx.is_empty());
1346 assert!(!report.event.rearm.intersects(SerialEventSet::RX));
1347 assert_eq!(read_test_reg(®s, 0x038) & rx_sources, rx_sources);
1348 }
1349
1350 #[test]
1351 fn set_config_preserves_enabled_tx_and_rx_paths() {
1352 let (regs, mut uart) = pl011_with_registers();
1353 regs.uartcr
1354 .write(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
1355
1356 uart.set_config(&Config::new()).unwrap();
1357
1358 let cr = regs.uartcr.extract();
1359 assert!(cr.is_set(UARTCR::UARTEN));
1360 assert!(cr.is_set(UARTCR::TXE));
1361 assert!(cr.is_set(UARTCR::RXE));
1362 }
1363
1364 #[test]
1365 fn set_config_busy_timeout_restores_every_configuration_register() {
1366 let (mut regs, mut uart) = pl011_with_registers();
1367 seed_config_registers(&mut regs);
1368 let before = config_register_snapshot(®s);
1369 write_test_reg(&mut regs, 0x018, UARTFR::BUSY::SET.value);
1370
1371 let result = uart.set_config(&Config::new().baudrate(115_200));
1372
1373 assert_eq!(result, Err(ConfigError::Timeout));
1374 assert_eq!(config_register_snapshot(®s), before);
1375 }
1376
1377 #[test]
1378 fn invalid_config_restores_every_configuration_register() {
1379 let (mut regs, mut uart) = pl011_with_registers();
1380 seed_config_registers(&mut regs);
1381 write_test_reg(&mut regs, 0x018, 0);
1382 let before = config_register_snapshot(®s);
1383
1384 let result = uart.set_config(&Config::new().baudrate(2_000_000));
1385
1386 assert_eq!(result, Err(ConfigError::InvalidBaudrate));
1387 assert_eq!(config_register_snapshot(®s), before);
1388 }
1389
1390 #[test]
1391 fn rx_available_mask_enables_timeout_and_error_interrupts() {
1392 let (regs, mut uart) = pl011_with_registers();
1393
1394 uart.set_irq_mask(SerialEventSet::RX);
1395
1396 let imsc = regs.uartimsc.extract();
1397 assert!(imsc.is_set(UARTIS::RX));
1398 assert!(imsc.is_set(UARTIS::RT));
1399 assert!(imsc.is_set(UARTIS::FE));
1400 assert!(imsc.is_set(UARTIS::PE));
1401 assert!(imsc.is_set(UARTIS::BE));
1402 assert!(imsc.is_set(UARTIS::OE));
1403 assert_eq!(uart.get_irq_mask(), SerialEventSet::RX);
1404 }
1405
1406 #[test]
1407 fn hard_irq_does_not_claim_rx_ready_without_mis() {
1408 let (mut regs, uart) = pl011_with_registers();
1409 let mut parts = uart.split();
1410
1411 parts.control.set_irq_mask(SerialEventSet::RX);
1412 write_test_reg(&mut regs, 0x040, 0);
1413 write_test_reg(&mut regs, 0x018, 0);
1414
1415 assert!(handle_irq(&mut parts.irq).0.is_none());
1416 }
1417
1418 #[test]
1419 fn port_rx_ready_is_visible_without_irq_event() {
1420 let (mut regs, mut uart) = pl011_with_registers();
1421
1422 uart.set_irq_mask(SerialEventSet::RX);
1423 write_test_reg(&mut regs, 0x040, 0);
1424 write_test_reg(&mut regs, 0x018, 0);
1425 regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1426
1427 let status = uart.poll_status();
1428 assert!(status.rx_ready());
1429 let sample = uart.read_rx().expect("RX sample should be available");
1430 assert_eq!(sample.byte, Some(b'r'));
1431 assert_eq!(sample.flag, RxFlag::Normal);
1432 }
1433
1434 #[test]
1435 fn rearm_remasks_rx_when_fifo_is_already_ready() {
1436 let (mut regs, mut uart) = pl011_with_registers();
1437 write_test_reg(&mut regs, 0x018, 0);
1438
1439 let ready = uart.rearm(SerialEventSet::RX);
1440
1441 assert_eq!(ready, SerialEventSet::RX_DATA);
1442 assert_eq!(
1443 read_test_reg(®s, 0x038) & imsc_for_events(SerialEventSet::RX),
1444 0
1445 );
1446 }
1447
1448 #[test]
1449 fn unknown_irq_source_masks_all_without_fifo_access() {
1450 let (mut regs, uart) = pl011_with_registers();
1451 let mut irq = uart.split().irq;
1452 write_test_reg(&mut regs, 0x000, 0x5a);
1453 write_test_reg(&mut regs, 0x038, u32::MAX);
1454 write_test_reg(&mut regs, 0x040, 1 << 31);
1455
1456 let event = handle_irq(&mut irq).0.unwrap();
1457
1458 assert!(event.events.contains(SerialEventSet::FAULT));
1459 assert_eq!(read_test_reg(®s, 0x038), 0);
1460 assert_eq!(read_test_reg(®s, 0x000), 0x5a);
1461 }
1462}