1use core::ptr::NonNull;
2
3use rdif_serial::{
4 Config, ConfigError, DataBits, IrqRxSink, Parity, RxErrorFlags, RxFlag, RxSample,
5 SerialEventSet, SerialIrqEvent, SplitUart, StopBits, UartInfo, UartIrq, UartParts, UartPort,
6};
7use tock_registers::{
8 LocalRegisterCopy, interfaces::*, register_bitfields, register_structs, registers::*,
9};
10
11use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
12
13register_bitfields! [
14 u32,
15
16 UARTDR [
18 DATA OFFSET(0) NUMBITS(8) [],
19 FE OFFSET(8) NUMBITS(1) [],
20 PE OFFSET(9) NUMBITS(1) [],
21 BE OFFSET(10) NUMBITS(1) [],
22 OE OFFSET(11) NUMBITS(1) []
23 ],
24
25 UARTRSR_ECR [
27 FE OFFSET(0) NUMBITS(1) [],
28 PE OFFSET(1) NUMBITS(1) [],
29 BE OFFSET(2) NUMBITS(1) [],
30 OE OFFSET(3) NUMBITS(1) []
31 ],
32
33 UARTFR [
35 CTS OFFSET(0) NUMBITS(1) [],
36 DSR OFFSET(1) NUMBITS(1) [],
37 DCD OFFSET(2) NUMBITS(1) [],
38 BUSY OFFSET(3) NUMBITS(1) [],
39 RXFE OFFSET(4) NUMBITS(1) [],
40 TXFF OFFSET(5) NUMBITS(1) [],
41 RXFF OFFSET(6) NUMBITS(1) [],
42 TXFE OFFSET(7) NUMBITS(1) [],
43 RI OFFSET(8) NUMBITS(1) []
44 ],
45
46 UARTIBRD [
48 BAUD_DIVINT OFFSET(0) NUMBITS(16) []
49 ],
50
51 UARTFBRD [
53 BAUD_DIVFRAC OFFSET(0) NUMBITS(6) []
54 ],
55
56 UARTLCR_H [
58 BRK OFFSET(0) NUMBITS(1) [],
59 PEN OFFSET(1) NUMBITS(1) [],
60 EPS OFFSET(2) NUMBITS(1) [],
61 STP2 OFFSET(3) NUMBITS(1) [],
62 FEN OFFSET(4) NUMBITS(1) [],
63 WLEN OFFSET(5) NUMBITS(2) [
64 FiveBit = 0,
65 SixBit = 1,
66 SevenBit = 2,
67 EightBit = 3
68 ],
69 SPS OFFSET(7) NUMBITS(1) []
70 ],
71
72 UARTCR [
74 UARTEN OFFSET(0) NUMBITS(1) [],
75 SIREN OFFSET(1) NUMBITS(1) [],
76 SIRLP OFFSET(2) NUMBITS(1) [],
77 LBE OFFSET(7) NUMBITS(1) [],
78 TXE OFFSET(8) NUMBITS(1) [],
79 RXE OFFSET(9) NUMBITS(1) [],
80 DTR OFFSET(10) NUMBITS(1) [],
81 RTS OFFSET(11) NUMBITS(1) [],
82 OUT1 OFFSET(12) NUMBITS(1) [],
83 OUT2 OFFSET(13) NUMBITS(1) [],
84 RTSEN OFFSET(14) NUMBITS(1) [],
85 CTSEN OFFSET(15) NUMBITS(1) []
86 ],
87
88 UARTIFLS [
90 TXIFLSEL OFFSET(0) NUMBITS(3) [],
91 RXIFLSEL OFFSET(3) NUMBITS(3) []
92 ],
93
94 UARTIS [
96 RIM OFFSET(0) NUMBITS(1) [],
97 CTSM OFFSET(1) NUMBITS(1) [],
98 DCDM OFFSET(2) NUMBITS(1) [],
99 DSRM OFFSET(3) NUMBITS(1) [],
100 RX OFFSET(4) NUMBITS(1) [],
101 TX OFFSET(5) NUMBITS(1) [],
102 RT OFFSET(6) NUMBITS(1) [],
103 FE OFFSET(7) NUMBITS(1) [],
104 PE OFFSET(8) NUMBITS(1) [],
105 BE OFFSET(9) NUMBITS(1) [],
106 OE OFFSET(10) NUMBITS(1) []
107 ],
108
109 UARTDMACR [
111 RXDMAE OFFSET(0) NUMBITS(1) [],
112 TXDMAE OFFSET(1) NUMBITS(1) [],
113 DMAONERR OFFSET(2) NUMBITS(1) []
114 ]
115];
116
117register_structs! {
118 pub Pl011Registers {
119 (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),
137 }
138}
139
140unsafe impl Sync for Pl011Registers {}
142
143pub struct Pl011 {
145 base: Reg,
146 clock_freq: u32,
147 saved_rx_status: Pl011RxStatus,
148}
149
150impl Pl011 {
151 pub fn new_no_clock(base: NonNull<u8>) -> Self {
156 let clock_freq = Self::detect_clock_frequency(base.as_ptr() as usize);
158 Self::new(base, clock_freq)
159 }
160
161 pub fn new(base: NonNull<u8>, clock_freq: u32) -> Self {
162 let base = Reg(base.cast());
163
164 Self {
165 base,
166 clock_freq,
167 saved_rx_status: Pl011RxStatus::empty(),
168 }
169 }
170
171 fn registers(&self) -> &Pl011Registers {
172 unsafe { &*self.base.0.as_ptr() }
173 }
174
175 fn current_baudrate(&self) -> u32 {
176 let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
177 let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
178 let divisor = ibrd * 64 + fbrd;
179 if divisor == 0 {
180 0
181 } else {
182 self.clock_freq * 64 / (16 * divisor)
183 }
184 }
185
186 fn detect_clock_frequency(base: usize) -> u32 {
188 let registers = unsafe { &*(base as *const Pl011Registers) };
190
191 use tock_registers::interfaces::Readable;
192 let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
193
194 if ibrd > 0 && ibrd <= 0xFFFF {
196 let estimated_clock = 16 * ibrd * 115200;
199
200 if (1_000_000..=100_000_000).contains(&estimated_clock) {
202 return estimated_clock;
203 }
204 }
205
206 24_000_000
208 }
209
210 fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
212 let bauddiv = self.clock_freq / (16 * baudrate);
218 let remainder = self.clock_freq % (16 * baudrate);
219 let fbrd = (remainder * 64 + (16 * baudrate / 2)) / (16 * baudrate);
220
221 if bauddiv == 0 || bauddiv > 0xFFFF {
222 return Err(ConfigError::InvalidBaudrate);
223 }
224
225 self.registers()
226 .uartibrd
227 .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
228 self.registers()
229 .uartfbrd
230 .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
231
232 Ok(())
233 }
234
235 fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
236 let wlen = match bits {
237 DataBits::Five => UARTLCR_H::WLEN::FiveBit,
238 DataBits::Six => UARTLCR_H::WLEN::SixBit,
239 DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
240 DataBits::Eight => UARTLCR_H::WLEN::EightBit,
241 };
242
243 self.registers().uartlcr_h.modify(wlen);
244 Ok(())
245 }
246
247 fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
248 match bits {
249 StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
250 StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
251 }
252
253 Ok(())
254 }
255
256 fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
257 match parity {
258 Parity::None => {
259 self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
261 }
262 Parity::Odd => {
263 self.registers()
265 .uartlcr_h
266 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
267 }
268 Parity::Even => {
269 self.registers()
271 .uartlcr_h
272 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
273 }
274 Parity::Mark => {
275 self.registers()
277 .uartlcr_h
278 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
279 }
280 Parity::Space => {
281 self.registers()
283 .uartlcr_h
284 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
285 }
286 }
287
288 Ok(())
289 }
290
291 pub fn open(&mut self) {
293 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
295
296 while self.registers().uartfr.is_set(UARTFR::BUSY) {
298 core::hint::spin_loop();
299 }
300
301 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
303
304 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
306
307 #[cfg(debug_assertions)]
309 {
310 let ifls = self.registers().uartifls.get();
311 let lcr_h = self.registers().uartlcr_h.get();
312 log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
313 log::debug!(" FIFO enabled: {}", lcr_h & (1 << 4) != 0);
314 log::debug!(" RX trigger level: 1/8");
315 log::debug!(" TX trigger level: 1/2");
316 }
317 self.registers().uartimsc.set(0); self.registers()
320 .uartcr
321 .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
322 }
323
324 pub fn set_irq_mask(&mut self, events: SerialEventSet) {
325 self.registers().uartimsc.set(imsc_for_events(events));
326 }
327
328 pub fn get_irq_mask(&self) -> SerialEventSet {
329 let imsc = self.registers().uartimsc.extract();
330 let mut events = SerialEventSet::empty();
331
332 if imsc.is_set(UARTIS::RX)
333 || imsc.is_set(UARTIS::RT)
334 || imsc.is_set(UARTIS::FE)
335 || imsc.is_set(UARTIS::PE)
336 || imsc.is_set(UARTIS::BE)
337 || imsc.is_set(UARTIS::OE)
338 {
339 events |= SerialEventSet::RX;
340 }
341 if imsc.is_set(UARTIS::TX) {
342 events |= SerialEventSet::TX_SPACE;
343 }
344
345 events
346 }
347
348 pub fn pending(&mut self, direction: SerialDirection) -> bool {
349 match direction {
350 SerialDirection::Input => !self.registers().uartfr.is_set(UARTFR::RXFE),
351 SerialDirection::Output => !self.registers().uartfr.is_set(UARTFR::TXFF),
352 }
353 }
354
355 pub fn poll_status(&mut self) -> SerialEvent {
356 let mut event = SerialEvent::empty();
357 let fr = self.registers().uartfr.extract();
358 if !fr.is_set(UARTFR::RXFE) {
359 event |= SerialEvent::RX_READY;
360 }
361 if !fr.is_set(UARTFR::TXFF) {
362 event |= SerialEvent::TX_READY;
363 }
364
365 let status =
366 self.saved_rx_status | Pl011RxStatus::from_rsr(self.registers().uartrsr_ecr.extract());
367 if status.intersects(Pl011RxStatus::FRAMING | Pl011RxStatus::PARITY | Pl011RxStatus::BREAK)
368 {
369 event |= SerialEvent::RX_ERROR;
370 }
371 if status.contains(Pl011RxStatus::OVERRUN) {
372 event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
373 }
374
375 event
376 }
377
378 pub fn try_write(&mut self, bytes: &[u8]) -> usize {
379 let mut written = 0;
380 for &byte in bytes {
381 let status = self.poll_status();
382 if !status.tx_ready() {
383 break;
384 }
385 self.write_byte(byte);
386 written += 1;
387 }
388 written
389 }
390
391 pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
392 let mut count = 0;
393 for byte in bytes.iter_mut() {
394 let status = self.poll_status();
395 if !status.rx_ready() && !status.rx_error() {
396 break;
397 }
398 match self.read_byte(status) {
399 Some(Ok(b)) => {
400 *byte = b;
401 }
402 Some(Err(TransferError::Overrun(b))) => {
403 *byte = b;
404 count += 1;
405 return Err(TransBytesError {
406 bytes_transferred: count,
407 kind: TransferError::Overrun(b),
408 });
409 }
410 Some(Err(e)) => {
411 return Err(TransBytesError {
412 bytes_transferred: count,
413 kind: e,
414 });
415 }
416 None => break,
417 }
418 count += 1;
419 }
420 Ok(count)
421 }
422
423 pub fn write_byte(&mut self, byte: u8) {
424 self.registers().uartdr.set(byte as _);
425 }
426
427 pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
428 if !status.rx_ready() && !status.rx_error() {
429 return None;
430 }
431
432 let sample = self.read_rx()?;
433 if sample.overrun {
434 return Some(Err(TransferError::Overrun(sample.byte.unwrap_or(0))));
435 }
436 match sample.flag {
437 RxFlag::Normal => sample.byte.map(Ok),
438 RxFlag::Break => Some(Err(TransferError::Break)),
439 RxFlag::Parity => Some(Err(TransferError::Parity)),
440 RxFlag::Framing => Some(Err(TransferError::Framing)),
441 }
442 }
443
444 pub fn read_rx(&mut self) -> Option<RxSample> {
445 let base = self.base;
446 let registers = unsafe { &*base.0.as_ptr() };
449 read_rx_sample(registers, &mut self.saved_rx_status)
450 }
451}
452
453fn read_rx_sample(
454 registers: &Pl011Registers,
455 saved_status: &mut Pl011RxStatus,
456) -> Option<RxSample> {
457 if registers.uartfr.is_set(UARTFR::RXFE) {
458 *saved_status |= Pl011RxStatus::from_rsr(registers.uartrsr_ecr.extract());
459 return saved_status.take_status_sample();
460 }
461
462 let dr = registers.uartdr.extract();
463 let data = dr.read(UARTDR::DATA) as u8;
464 let status = Pl011RxStatus::from_data(dr);
465 if !status.is_empty() {
466 saved_status.remove(status);
467 }
468
469 Some(RxSample {
470 byte: Some(data),
471 flag: status.flag(),
472 overrun: status.contains(Pl011RxStatus::OVERRUN),
473 })
474}
475
476fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
477 let mut errors = match sample.flag {
478 RxFlag::Normal => RxErrorFlags::empty(),
479 RxFlag::Break => RxErrorFlags::BREAK,
480 RxFlag::Parity => RxErrorFlags::PARITY,
481 RxFlag::Framing => RxErrorFlags::FRAMING,
482 };
483 if sample.overrun {
484 errors |= RxErrorFlags::OVERRUN;
485 }
486 errors
487}
488
489bitflags::bitflags! {
490 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
491 struct Pl011RxStatus: u32 {
492 const FRAMING = 1 << 0;
493 const PARITY = 1 << 1;
494 const BREAK = 1 << 2;
495 const OVERRUN = 1 << 3;
496 }
497}
498
499impl Pl011RxStatus {
500 fn to_irq_errors(self) -> RxErrorFlags {
501 let mut errors = RxErrorFlags::empty();
502 if self.contains(Self::BREAK) {
503 errors |= RxErrorFlags::BREAK;
504 }
505 if self.contains(Self::PARITY) {
506 errors |= RxErrorFlags::PARITY;
507 }
508 if self.contains(Self::FRAMING) {
509 errors |= RxErrorFlags::FRAMING;
510 }
511 if self.contains(Self::OVERRUN) {
512 errors |= RxErrorFlags::OVERRUN;
513 }
514 errors
515 }
516
517 fn from_data(dr: LocalRegisterCopy<u32, UARTDR::Register>) -> Self {
518 let mut status = Self::empty();
519 if dr.is_set(UARTDR::FE) {
520 status |= Self::FRAMING;
521 }
522 if dr.is_set(UARTDR::PE) {
523 status |= Self::PARITY;
524 }
525 if dr.is_set(UARTDR::BE) {
526 status |= Self::BREAK;
527 }
528 if dr.is_set(UARTDR::OE) {
529 status |= Self::OVERRUN;
530 }
531 status
532 }
533
534 fn from_irq_status(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> Self {
535 let mut status = Self::empty();
536 if mis.is_set(UARTIS::FE) {
537 status |= Self::FRAMING;
538 }
539 if mis.is_set(UARTIS::PE) {
540 status |= Self::PARITY;
541 }
542 if mis.is_set(UARTIS::BE) {
543 status |= Self::BREAK;
544 }
545 if mis.is_set(UARTIS::OE) {
546 status |= Self::OVERRUN;
547 }
548 status
549 }
550
551 fn from_rsr(rsr: LocalRegisterCopy<u32, UARTRSR_ECR::Register>) -> Self {
552 let mut status = Self::empty();
553 if rsr.is_set(UARTRSR_ECR::FE) {
554 status |= Self::FRAMING;
555 }
556 if rsr.is_set(UARTRSR_ECR::PE) {
557 status |= Self::PARITY;
558 }
559 if rsr.is_set(UARTRSR_ECR::BE) {
560 status |= Self::BREAK;
561 }
562 if rsr.is_set(UARTRSR_ECR::OE) {
563 status |= Self::OVERRUN;
564 }
565 status
566 }
567
568 fn flag(self) -> RxFlag {
569 if self.contains(Self::BREAK) {
570 RxFlag::Break
571 } else if self.contains(Self::PARITY) {
572 RxFlag::Parity
573 } else if self.contains(Self::FRAMING) {
574 RxFlag::Framing
575 } else {
576 RxFlag::Normal
577 }
578 }
579
580 fn take_status_sample(&mut self) -> Option<RxSample> {
581 if self.is_empty() {
582 return None;
583 }
584
585 let status = *self;
586 *self = Self::empty();
587 Some(RxSample {
588 byte: None,
589 flag: status.flag(),
590 overrun: status.contains(Self::OVERRUN),
591 })
592 }
593}
594
595#[derive(Clone, Copy, PartialEq, Eq)]
596struct Reg(NonNull<Pl011Registers>);
597
598unsafe impl Send for Reg {}
599unsafe impl Sync for Reg {}
600
601pub struct Pl011Irq {
603 base: Reg,
604 saved_rx_status: Pl011RxStatus,
605}
606
607impl Pl011Irq {
608 fn registers(&self) -> &Pl011Registers {
609 unsafe { &*self.base.0.as_ptr() }
612 }
613}
614
615impl UartIrq for Pl011Irq {
616 fn handle(&mut self, rx: &mut dyn IrqRxSink) -> Option<SerialIrqEvent> {
617 const RX_SAMPLE_BUDGET: usize = 256;
618
619 let mis = self.registers().uartmis.extract();
620 let active = mis.get();
621 if active == 0 {
622 return None;
623 }
624
625 let mut events = events_from_mis(mis);
626 if active & !0x7ff != 0 {
627 events |= SerialEventSet::FAULT;
628 }
629 let mut rx_errors = rx_errors_from_mis(mis);
630 if events.intersects(SerialEventSet::RX) {
631 let base = self.base;
632 let registers = unsafe { &*base.0.as_ptr() };
635 for _ in 0..RX_SAMPLE_BUDGET {
636 let Some(sample) = read_rx_sample(registers, &mut self.saved_rx_status) else {
637 break;
638 };
639 rx_errors |= rx_errors_from_sample(sample);
640 rx.push(sample);
641 }
642 }
643
644 let rearm = events & SerialEventSet::TX_SPACE;
645 if events.contains(SerialEventSet::FAULT) {
646 self.registers().uartimsc.set(0);
647 } else if !rearm.is_empty() {
648 let enabled = self.registers().uartimsc.get();
649 self.registers()
650 .uartimsc
651 .set(enabled & !imsc_for_events(rearm));
652 }
653 self.registers().uarticr.set(active);
654
655 Some(SerialIrqEvent {
656 events,
657 rx_errors,
658 rearm,
659 })
660 }
661}
662
663impl UartPort for Pl011 {
664 fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
665 self.open();
666 self.set_config(config)?;
667 self.mask_all();
668 Ok(())
669 }
670
671 fn shutdown(&mut self) {
672 self.registers().uartimsc.set(0);
673 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
674 }
675
676 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
677 use tock_registers::interfaces::Readable;
678
679 let original_cr = self.registers().uartcr.extract(); self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR); while self.registers().uartfr.is_set(UARTFR::BUSY) {
686 core::hint::spin_loop();
687 }
688
689 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
691
692 if let Some(baudrate) = config.baudrate {
694 self.set_baudrate_internal(baudrate)?;
695 }
696 if let Some(data_bits) = config.data_bits {
697 self.set_data_bits_internal(data_bits)?;
698 }
699 if let Some(stop_bits) = config.stop_bits {
700 self.set_stop_bits_internal(stop_bits)?;
701 }
702 if let Some(parity) = config.parity {
703 self.set_parity_internal(parity)?;
704 }
705
706 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
708
709 if original_cr.is_set(UARTCR::UARTEN) {
711 self.registers().uartcr.modify(
712 UARTCR::UARTEN.val(original_cr.read(UARTCR::UARTEN))
713 + UARTCR::TXE.val(original_cr.read(UARTCR::TXE))
714 + UARTCR::RXE.val(original_cr.read(UARTCR::RXE)),
715 );
716 }
717
718 Ok(())
719 }
720
721 fn read_rx(&mut self) -> Option<RxSample> {
722 Pl011::read_rx(self)
723 }
724
725 fn write_tx(&mut self, bytes: &[u8]) -> usize {
726 let mut written = 0;
727 for &byte in bytes {
728 if self.registers().uartfr.is_set(UARTFR::TXFF) {
729 break;
730 }
731 self.registers().uartdr.set(byte as u32);
732 written += 1;
733 }
734 written
735 }
736
737 fn tx_idle(&mut self) -> bool {
738 let fr = self.registers().uartfr.extract();
739 !fr.is_set(UARTFR::BUSY) && !fr.is_set(UARTFR::TXFF)
740 }
741
742 fn mask_all(&mut self) {
743 self.registers().uartimsc.set(0);
744 }
745
746 fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
747 let enabled = self.registers().uartimsc.get() | imsc_for_events(sources);
748 self.registers().uartimsc.set(enabled);
749
750 let fr = self.registers().uartfr.extract();
751 let rsr = self.registers().uartrsr_ecr.extract();
752 let mut ready = SerialEventSet::empty();
753 if sources.intersects(SerialEventSet::RX) && !fr.is_set(UARTFR::RXFE) {
754 ready |= SerialEventSet::RX_DATA;
755 }
756 if sources.contains(SerialEventSet::RX_STATUS) && !Pl011RxStatus::from_rsr(rsr).is_empty() {
757 ready |= SerialEventSet::RX_STATUS;
758 }
759 if sources.contains(SerialEventSet::TX_SPACE) && !fr.is_set(UARTFR::TXFF) {
760 ready |= SerialEventSet::TX_SPACE;
761 }
762 if !ready.is_empty() {
763 self.registers()
764 .uartimsc
765 .set(enabled & !imsc_for_events(ready));
766 }
767 ready
768 }
769}
770
771impl SplitUart for Pl011 {
772 type Port = Self;
773 type Irq = Pl011Irq;
774
775 fn runtime_info(&self) -> UartInfo {
776 UartInfo {
777 name: "PL011 UART",
778 register_base: self.base.0.as_ptr() as usize,
779 initial_baudrate: self.current_baudrate(),
780 }
781 }
782
783 fn split(self) -> UartParts<Self::Port, Self::Irq> {
784 let irq = Pl011Irq {
785 base: self.base,
786 saved_rx_status: Pl011RxStatus::empty(),
787 };
788 UartParts::new(self, irq)
789 }
790}
791
792impl PollingUart for Pl011 {
793 fn poll_status(&mut self) -> SerialEvent {
794 Pl011::poll_status(self)
795 }
796
797 fn write_byte(&mut self, byte: u8) {
798 Pl011::write_byte(self, byte);
799 }
800
801 fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
802 Pl011::read_byte(self, status)
803 }
804}
805
806fn events_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> SerialEventSet {
807 let mut events = SerialEventSet::empty();
808 if mis.is_set(UARTIS::RX) {
809 events |= SerialEventSet::RX_DATA;
810 }
811 if mis.is_set(UARTIS::RT) {
812 events |= SerialEventSet::RX_TIMEOUT;
813 }
814 if mis.is_set(UARTIS::FE)
815 || mis.is_set(UARTIS::PE)
816 || mis.is_set(UARTIS::BE)
817 || mis.is_set(UARTIS::OE)
818 {
819 events |= SerialEventSet::RX_STATUS;
820 }
821 if mis.is_set(UARTIS::TX) {
822 events |= SerialEventSet::TX_SPACE;
823 }
824 if mis.is_set(UARTIS::CTSM)
825 || mis.is_set(UARTIS::DSRM)
826 || mis.is_set(UARTIS::DCDM)
827 || mis.is_set(UARTIS::RIM)
828 {
829 events |= SerialEventSet::MODEM_STATUS;
830 }
831 events
832}
833
834fn rx_errors_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> RxErrorFlags {
835 Pl011RxStatus::from_irq_status(mis).to_irq_errors()
836}
837
838fn imsc_for_events(events: SerialEventSet) -> u32 {
839 let mut imsc = 0;
840 if events.intersects(SerialEventSet::RX) {
841 imsc |= UARTIS::RX::SET.value
842 | UARTIS::RT::SET.value
843 | UARTIS::FE::SET.value
844 | UARTIS::PE::SET.value
845 | UARTIS::BE::SET.value
846 | UARTIS::OE::SET.value;
847 }
848 if events.contains(SerialEventSet::TX_SPACE) {
849 imsc |= UARTIS::TX::SET.value;
850 }
851 if events.contains(SerialEventSet::MODEM_STATUS) {
852 imsc |= UARTIS::RIM::SET.value
853 | UARTIS::CTSM::SET.value
854 | UARTIS::DCDM::SET.value
855 | UARTIS::DSRM::SET.value;
856 }
857 imsc
858}
859
860impl Pl011 {
862 pub fn enable_fifo(&self, enable: bool) {
864 if enable {
865 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
866 } else {
867 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
868 }
869 }
870
871 pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
873 let rx_iflsel = match rx_level {
881 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
887
888 let tx_iflsel = match tx_level {
889 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
895
896 self.registers()
897 .uartifls
898 .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
899 }
900}
901
902#[cfg(test)]
905mod tests {
906 use core::ptr::NonNull;
907 use std::{boxed::Box, vec::Vec};
908
909 use super::*;
910
911 #[derive(Default)]
912 struct CollectRx(Vec<RxSample>);
913
914 impl IrqRxSink for CollectRx {
915 fn push(&mut self, sample: RxSample) {
916 self.0.push(sample);
917 }
918 }
919
920 fn handle_irq(irq: &mut impl UartIrq) -> (Option<SerialIrqEvent>, Vec<RxSample>) {
921 let mut rx = CollectRx::default();
922 let event = irq.handle(&mut rx);
923 (event, rx.0)
924 }
925
926 fn pl011_with_registers() -> (Box<Pl011Registers>, Pl011) {
927 let mut regs = Box::new(unsafe { core::mem::zeroed::<Pl011Registers>() });
928 let ptr = NonNull::from(regs.as_mut()).cast::<u8>();
929 let uart = Pl011::new(ptr, 24_000_000);
930 (regs, uart)
931 }
932
933 fn pl011_with_overrun_data() -> (Box<Pl011Registers>, Pl011) {
934 let (regs, uart) = pl011_with_registers();
935 regs.uartdr
936 .set((UARTDR::DATA.val(0xab) + UARTDR::OE::SET).into());
937 (regs, uart)
938 }
939
940 fn write_test_reg(regs: &mut Pl011Registers, offset: usize, value: u32) {
941 unsafe {
942 (regs as *mut Pl011Registers)
943 .cast::<u32>()
944 .add(offset / core::mem::size_of::<u32>())
945 .write_volatile(value);
946 }
947 }
948
949 fn read_test_reg(regs: &Pl011Registers, offset: usize) -> u32 {
950 unsafe {
951 (regs as *const Pl011Registers)
952 .cast::<u32>()
953 .add(offset / core::mem::size_of::<u32>())
954 .read_volatile()
955 }
956 }
957
958 fn started_parts(uart: Pl011) -> UartParts<Pl011, Pl011Irq> {
959 let mut parts = uart.split();
960 parts.port.startup(&Config::new()).unwrap();
961 parts
962 }
963
964 #[test]
965 fn raw_rx_reports_overrun_instead_of_swallowing_it() {
966 let (_regs, mut uart) = pl011_with_overrun_data();
967
968 let mut buf = [0];
969 let err = uart
970 .try_read(&mut buf)
971 .expect_err("overrun must be reported to the caller");
972
973 assert_eq!(buf[0], 0xab);
974 assert_eq!(err.bytes_transferred, 1);
975 assert_eq!(err.kind, TransferError::Overrun(0xab));
976 }
977
978 #[test]
979 fn raw_rx_sample_reports_overrun_instead_of_swallowing_it() {
980 let (mut regs, uart) = pl011_with_overrun_data();
981 let mut parts = uart.split();
982
983 write_test_reg(&mut regs, 0x040, UARTIS::OE::SET.value);
984 let (event, samples) = handle_irq(&mut parts.irq);
985 let event = event.unwrap();
986 assert!(event.events.contains(SerialEventSet::RX_STATUS));
987 assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
988 assert_eq!(
989 samples.len(),
990 256,
991 "the hard IRQ must enforce its RX budget"
992 );
993 let sample = samples[0];
994 assert_eq!(sample.byte, Some(0xab));
995 assert_eq!(sample.flag, RxFlag::Normal);
996 assert!(sample.overrun);
997 }
998
999 #[test]
1000 fn rx_irq_keeps_source_enabled_after_bounded_fifo_drain() {
1001 let (mut regs, uart) = pl011_with_registers();
1002 let mut irq = uart.split().irq;
1003 let rx_mask = imsc_for_events(SerialEventSet::RX);
1004 write_test_reg(&mut regs, 0x038, rx_mask);
1005 write_test_reg(&mut regs, 0x040, UARTIS::RX::SET.value);
1006 write_test_reg(&mut regs, 0x018, 0);
1007 regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1008
1009 let (event, samples) = handle_irq(&mut irq);
1010 let event = event.unwrap();
1011
1012 assert!(event.events.contains(SerialEventSet::RX_DATA));
1013 assert!(!event.rearm.intersects(SerialEventSet::RX));
1014 assert_eq!(samples.len(), 256);
1015 assert_eq!(read_test_reg(®s, 0x038) & rx_mask, rx_mask);
1016 }
1017
1018 #[test]
1019 fn irq_status_without_rx_byte_is_preserved_after_irq_ack() {
1020 let (mut regs, uart) = pl011_with_registers();
1021 let mut parts = uart.split();
1022
1023 write_test_reg(
1024 &mut regs,
1025 0x040,
1026 UARTIS::OE::SET.value | UARTIS::PE::SET.value,
1027 );
1028 write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1029
1030 let event = handle_irq(&mut parts.irq).0.unwrap();
1031 assert!(event.events.contains(SerialEventSet::RX_STATUS));
1032 assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1033 assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1034 assert!(parts.port.read_rx().is_none());
1035 }
1036
1037 #[test]
1038 fn tx_irq_exposes_space_without_owning_a_software_fifo() {
1039 let (mut regs, uart) = pl011_with_registers();
1040 let mut parts = started_parts(uart);
1041
1042 write_test_reg(&mut regs, 0x018, 0);
1043 write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1044 let event = handle_irq(&mut parts.irq).0.unwrap();
1045 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1046 assert_eq!(parts.port.write_tx(b"x"), 1);
1047 assert_eq!(regs.uartdr.get() as u8, b'x');
1048 }
1049
1050 #[test]
1051 fn tx_irq_endpoint_acknowledges_tx_interrupt() {
1052 let (mut regs, uart) = pl011_with_registers();
1053 let mut irq = uart.split().irq;
1054
1055 write_test_reg(&mut regs, 0x000, 0x5a);
1056 write_test_reg(&mut regs, 0x038, UARTIS::TX::SET.value);
1057 write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1058 let event = handle_irq(&mut irq).0.unwrap();
1059
1060 assert!(event.events.contains(SerialEventSet::TX_SPACE));
1061 assert_eq!(event.rearm, SerialEventSet::TX_SPACE);
1062 assert_eq!(
1063 read_test_reg(®s, 0x044) & UARTIS::TX::SET.value,
1064 UARTIS::TX::SET.value
1065 );
1066 assert_eq!(read_test_reg(®s, 0x038) & UARTIS::TX::SET.value, 0);
1067 assert_eq!(read_test_reg(®s, 0x000), 0x5a);
1068 }
1069
1070 #[test]
1071 fn set_config_preserves_enabled_tx_and_rx_paths() {
1072 let (regs, mut uart) = pl011_with_registers();
1073 regs.uartcr
1074 .write(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
1075
1076 uart.set_config(&Config::new()).unwrap();
1077
1078 let cr = regs.uartcr.extract();
1079 assert!(cr.is_set(UARTCR::UARTEN));
1080 assert!(cr.is_set(UARTCR::TXE));
1081 assert!(cr.is_set(UARTCR::RXE));
1082 }
1083
1084 #[test]
1085 fn rx_available_mask_enables_timeout_and_error_interrupts() {
1086 let (regs, mut uart) = pl011_with_registers();
1087
1088 uart.set_irq_mask(SerialEventSet::RX);
1089
1090 let imsc = regs.uartimsc.extract();
1091 assert!(imsc.is_set(UARTIS::RX));
1092 assert!(imsc.is_set(UARTIS::RT));
1093 assert!(imsc.is_set(UARTIS::FE));
1094 assert!(imsc.is_set(UARTIS::PE));
1095 assert!(imsc.is_set(UARTIS::BE));
1096 assert!(imsc.is_set(UARTIS::OE));
1097 assert_eq!(uart.get_irq_mask(), SerialEventSet::RX);
1098 }
1099
1100 #[test]
1101 fn hard_irq_does_not_claim_rx_ready_without_mis() {
1102 let (mut regs, uart) = pl011_with_registers();
1103 let mut parts = uart.split();
1104
1105 parts.port.set_irq_mask(SerialEventSet::RX);
1106 write_test_reg(&mut regs, 0x040, 0);
1107 write_test_reg(&mut regs, 0x018, 0);
1108
1109 assert!(handle_irq(&mut parts.irq).0.is_none());
1110 }
1111
1112 #[test]
1113 fn port_rx_ready_is_visible_without_irq_event() {
1114 let (mut regs, mut uart) = pl011_with_registers();
1115
1116 uart.set_irq_mask(SerialEventSet::RX);
1117 write_test_reg(&mut regs, 0x040, 0);
1118 write_test_reg(&mut regs, 0x018, 0);
1119 regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1120
1121 let status = uart.poll_status();
1122 assert!(status.rx_ready());
1123 let sample = uart.read_rx().expect("RX sample should be available");
1124 assert_eq!(sample.byte, Some(b'r'));
1125 assert_eq!(sample.flag, RxFlag::Normal);
1126 }
1127
1128 #[test]
1129 fn rearm_remasks_rx_when_fifo_is_already_ready() {
1130 let (mut regs, mut uart) = pl011_with_registers();
1131 write_test_reg(&mut regs, 0x018, 0);
1132
1133 let ready = uart.rearm(SerialEventSet::RX);
1134
1135 assert_eq!(ready, SerialEventSet::RX_DATA);
1136 assert_eq!(
1137 read_test_reg(®s, 0x038) & imsc_for_events(SerialEventSet::RX),
1138 0
1139 );
1140 }
1141
1142 #[test]
1143 fn unknown_irq_source_masks_all_without_fifo_access() {
1144 let (mut regs, uart) = pl011_with_registers();
1145 let mut irq = uart.split().irq;
1146 write_test_reg(&mut regs, 0x000, 0x5a);
1147 write_test_reg(&mut regs, 0x038, u32::MAX);
1148 write_test_reg(&mut regs, 0x040, 1 << 31);
1149
1150 let event = handle_irq(&mut irq).0.unwrap();
1151
1152 assert!(event.events.contains(SerialEventSet::FAULT));
1153 assert_eq!(read_test_reg(®s, 0x038), 0);
1154 assert_eq!(read_test_reg(®s, 0x000), 0x5a);
1155 }
1156}