1mod registers;
9
10use bitflags::Flags;
11use rdif_serial::{
12 Config, ConfigError, DataBits, IRQ_RX_BATCH_CAPACITY, IrqRxBatch, Parity, RxErrorFlags, RxFlag,
13 RxSample, SerialEventSet, SerialIrqEvent, SerialIrqReport, SerialParts, SplitUart, StopBits,
14 UartEmergencyTx, UartInfo, UartIrq, UartPort,
15};
16use registers::*;
17
18use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
19
20pub mod dw_apb;
21#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
22mod pio;
23pub mod rockchip_fiq;
24mod mmio;
26
27pub use dw_apb::*;
28pub use mmio::*;
29#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
30pub use pio::*;
31pub use rockchip_fiq::*;
32
33pub trait Kind: Clone + Send + Sync + 'static {
34 fn read_reg(&self, reg: u8) -> u8;
35 fn write_reg(&self, reg: u8, val: u8);
36 fn get_base(&self) -> usize;
37
38 fn ack_busy_detect(&self) {}
39
40 fn set_baudrate(&self, clock_freq: u32, baudrate: u32) -> Result<(), ConfigError> {
43 if baudrate == 0 || clock_freq == 0 {
44 return Err(ConfigError::InvalidBaudrate);
45 }
46
47 let divisor = clock_freq / (16 * baudrate);
48 if divisor == 0 || divisor > 0xFFFF {
49 return Err(ConfigError::InvalidBaudrate);
50 }
51
52 let lcr: LineControlFlags = self.read_flags(UART_LCR);
53 self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
54
55 self.write_reg(UART_DLL, (divisor & 0xFF) as u8);
56 self.write_reg(UART_DLH, ((divisor >> 8) & 0xFF) as u8);
57
58 self.write_flags(UART_LCR, lcr);
59
60 Ok(())
61 }
62
63 fn baudrate(&self, clock_freq: u32) -> u32 {
64 let lcr: LineControlFlags = self.read_flags(UART_LCR);
65 self.write_flags(UART_LCR, lcr | LineControlFlags::DIVISOR_LATCH_ACCESS);
66
67 let dll = self.read_reg(UART_DLL) as u16;
68 let dlh = self.read_reg(UART_DLH) as u16;
69
70 self.write_flags(UART_LCR, lcr);
71
72 let divisor = dll | (dlh << 8);
73
74 if divisor == 0 {
75 return 0;
76 }
77
78 clock_freq / (16 * divisor as u32)
79 }
80
81 fn init(&self) {
82 self.write_flags(UART_IER, InterruptEnableFlags::empty());
83 self.write_flags(
84 UART_FCR,
85 FifoControlFlags::ENABLE_FIFO
86 | FifoControlFlags::CLEAR_RECEIVER_FIFO
87 | FifoControlFlags::CLEAR_TRANSMITTER_FIFO
88 | FifoControlFlags::TRIGGER_1_BYTE,
89 );
90
91 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
92 mcr.insert(
93 ModemControlFlags::DATA_TERMINAL_READY
94 | ModemControlFlags::REQUEST_TO_SEND
95 | ModemControlFlags::OUT_2,
96 );
97 self.write_flags(UART_MCR, mcr);
98 }
99
100 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
102 F::from_bits_retain(self.read_reg(reg))
103 }
104
105 fn write_flags<F: Flags<Bits = u8>>(&self, reg: u8, val: F) {
106 self.write_reg(reg, val.bits());
107 }
108}
109
110pub struct Ns16550<T: Kind> {
111 pub(crate) base: T,
112 pub(crate) clock_freq: u32,
113 pub(crate) saved_lsr: LineStatusFlags,
114}
115
116pub struct Ns16550Irq<T: Kind> {
118 base: T,
119 saved_lsr: LineStatusFlags,
120}
121
122pub struct Ns16550EmergencyTx<T: Kind> {
124 base: T,
125}
126
127impl<T: Kind> Ns16550EmergencyTx<T> {
128 fn mask_interrupts(&self) {
129 self.base
130 .write_flags(UART_IER, InterruptEnableFlags::empty());
131 let _: InterruptEnableFlags = self.base.read_flags(UART_IER);
133 }
134}
135
136impl<T: Kind> UartEmergencyTx for Ns16550EmergencyTx<T> {
137 unsafe fn mask_interrupts_unlocked(&self) {
138 self.mask_interrupts();
139 }
140
141 unsafe fn try_write_unlocked(&self, bytes: &[u8]) -> usize {
142 let mut written = 0;
143 for &byte in bytes.iter().take(UART_FIFO_SIZE as usize) {
144 let status: LineStatusFlags = self.base.read_flags(UART_LSR);
145 if !status.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
146 break;
147 }
148 self.base.write_reg(UART_THR, byte);
149 written += 1;
150 }
151 written
152 }
153}
154
155impl<T: Kind> Ns16550Irq<T> {
156 fn next_event(&self) -> Option<SerialEventSet> {
157 let iir: InterruptIdentificationFlags = self.base.read_flags(UART_IIR);
158 if iir.bits() & (UART_IIR_ID | UART_IIR_NO_INT) == UART_IIR_BUSY {
159 return Some(SerialEventSet::BUSY_DETECT);
160 }
161 if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
162 return None;
163 }
164
165 let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
166 let event = if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
167 SerialEventSet::RX_STATUS
168 } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE {
169 SerialEventSet::RX_DATA
170 } else if interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT {
171 SerialEventSet::RX_TIMEOUT
172 } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
173 SerialEventSet::TX_SPACE
174 } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
175 SerialEventSet::MODEM_STATUS
176 } else {
177 SerialEventSet::FAULT
178 };
179 Some(event)
180 }
181
182 fn ack_modem_status(&self) {
183 let _: ModemStatusFlags = self.base.read_flags(UART_MSR);
184 }
185
186 fn ack_busy_detect(&self) {
187 self.base.ack_busy_detect();
188 }
189
190 fn mask_sources(&self, events: SerialEventSet) {
191 let mut ier: InterruptEnableFlags = self.base.read_flags(UART_IER);
192 ier.remove(interrupt_enable_for_events(events));
193 self.base.write_flags(UART_IER, ier);
194 }
195}
196
197impl<T: Kind> UartIrq for Ns16550Irq<T> {
198 fn mask(&mut self, sources: SerialEventSet) {
199 self.mask_sources(sources);
200 }
201
202 fn handle(&mut self) -> Option<SerialIrqReport> {
203 const IRQ_PASS_BUDGET: usize = 32;
204
205 let mut event = SerialIrqEvent::default();
206 let mut rx = IrqRxBatch::new();
207 let mut rx_samples = 0;
208 let mut pass_budget_exhausted = false;
209 for pass in 0..IRQ_PASS_BUDGET {
210 let Some(current) = self.next_event() else {
211 break;
212 };
213 pass_budget_exhausted = pass + 1 == IRQ_PASS_BUDGET;
214 event.events |= current;
215 if current.intersects(SerialEventSet::RX) {
216 let before = rx_samples;
217 while rx_samples < IRQ_RX_BATCH_CAPACITY {
218 let Some(sample) = read_rx_sample(&self.base, &mut self.saved_lsr) else {
219 break;
220 };
221 event.rx_errors |= rx_errors_from_sample(sample);
222 rx.try_push(sample)
223 .expect("the fixed NS16550 IRQ loop cannot overflow its RX batch");
224 rx_samples += 1;
225 }
226 if rx_samples == IRQ_RX_BATCH_CAPACITY || rx_samples == before {
227 break;
228 }
229 }
230 if current.contains(SerialEventSet::MODEM_STATUS) {
231 self.ack_modem_status();
232 }
233 if current.contains(SerialEventSet::BUSY_DETECT) {
234 self.ack_busy_detect();
235 }
236 if current.contains(SerialEventSet::FAULT) {
237 self.base
238 .write_flags(UART_IER, InterruptEnableFlags::empty());
239 break;
240 }
241
242 let rearm = current & SerialEventSet::TX_SPACE;
243 if !rearm.is_empty() {
244 self.mask_sources(rearm);
245 event.rearm |= rearm;
246 }
247 }
248
249 let defer_rx = rx.len() == IRQ_RX_BATCH_CAPACITY
250 || event.rx_errors.contains(RxErrorFlags::OVERRUN)
251 || (pass_budget_exhausted && event.events.has_rx());
252 if defer_rx && !event.events.contains(SerialEventSet::FAULT) {
253 self.mask_sources(SerialEventSet::RX);
254 event.rearm |= SerialEventSet::RX;
255 }
256
257 (!event.events.is_empty()).then_some(SerialIrqReport::new(event, rx))
258 }
259}
260
261impl<T: Kind> UartPort for Ns16550<T> {
262 fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
263 let original_ier: InterruptEnableFlags = self.read_flags(UART_IER);
264 self.write_flags(UART_IER, InterruptEnableFlags::empty());
265 if let Err(error) = self.set_config(config) {
266 self.write_flags(UART_IER, original_ier);
270 return Err(error);
271 }
272 self.enable_fifo(true);
273
274 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
275 mcr.insert(
276 ModemControlFlags::DATA_TERMINAL_READY
277 | ModemControlFlags::REQUEST_TO_SEND
278 | ModemControlFlags::OUT_2,
279 );
280 self.write_flags(UART_MCR, mcr);
281 self.saved_lsr = LineStatusFlags::empty();
282 Ok(())
283 }
284
285 fn shutdown(&mut self) {
286 self.close();
287 }
288
289 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
290 if let Some(baudrate) = config.baudrate {
292 self.set_baudrate_internal(baudrate)?;
293 }
294
295 if let Some(data_bits) = config.data_bits {
297 self.set_data_bits_internal(data_bits)?;
298 }
299
300 if let Some(stop_bits) = config.stop_bits {
302 self.set_stop_bits_internal(stop_bits)?;
303 }
304
305 if let Some(parity) = config.parity {
307 self.set_parity_internal(parity)?;
308 }
309 Ok(())
310 }
311
312 fn read_rx(&mut self) -> Option<RxSample> {
313 Ns16550::read_rx(self)
314 }
315
316 fn discard_rx(&mut self) {
317 self.saved_lsr = LineStatusFlags::empty();
318 self.write_flags(
319 UART_FCR,
320 FifoControlFlags::ENABLE_FIFO
321 | FifoControlFlags::CLEAR_RECEIVER_FIFO
322 | FifoControlFlags::TRIGGER_8_BYTES,
323 );
324 }
325
326 fn write_tx(&mut self, bytes: &[u8]) -> usize {
327 self.try_write(bytes)
328 }
329
330 fn discard_tx(&mut self) -> bool {
331 self.write_flags(
332 UART_FCR,
333 FifoControlFlags::ENABLE_FIFO
334 | FifoControlFlags::CLEAR_TRANSMITTER_FIFO
335 | FifoControlFlags::TRIGGER_8_BYTES,
336 );
337 true
338 }
339
340 fn tx_idle(&mut self) -> bool {
341 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
342 lsr.contains(
343 LineStatusFlags::TRANSMITTER_HOLDING_EMPTY | LineStatusFlags::TRANSMITTER_EMPTY,
344 )
345 }
346
347 fn mask(&mut self, sources: SerialEventSet) {
348 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
349 ier.remove(interrupt_enable_for_events(sources));
350 self.write_flags(UART_IER, ier);
351 }
352
353 fn mask_all(&mut self) {
354 self.write_flags(UART_IER, InterruptEnableFlags::empty());
355 }
356
357 fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
358 let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
359 ier.insert(interrupt_enable_for_events(sources));
360 self.write_flags(UART_IER, ier);
361
362 let lsr = self.read_lsr_preserving();
363 let mut ready = SerialEventSet::empty();
364 if sources.intersects(SerialEventSet::RX)
365 && lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK)
366 {
367 ready |= if lsr.contains(LineStatusFlags::DATA_READY) {
368 SerialEventSet::RX_DATA
369 } else {
370 SerialEventSet::RX_STATUS
371 };
372 }
373 if sources.contains(SerialEventSet::TX_SPACE)
374 && lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY)
375 {
376 ready |= SerialEventSet::TX_SPACE;
377 }
378 if !ready.is_empty() {
379 ier.remove(interrupt_enable_for_events(ready));
380 self.write_flags(UART_IER, ier);
381 }
382 ready
383 }
384}
385
386impl<T: Kind> SplitUart for Ns16550<T> {
387 type Control = Self;
388 type Irq = Ns16550Irq<T>;
389 type EmergencyTx = Ns16550EmergencyTx<T>;
390
391 fn runtime_info(&self) -> UartInfo {
392 UartInfo {
393 name: "NS16550 UART",
394 register_base: self.base.get_base(),
395 initial_baudrate: self.base.baudrate(self.clock_freq),
396 }
397 }
398
399 fn split(self) -> SerialParts<Self::Control, Self::Irq, Self::EmergencyTx> {
400 let irq = Ns16550Irq {
401 base: self.base.clone(),
402 saved_lsr: LineStatusFlags::empty(),
403 };
404 let emergency_tx = Ns16550EmergencyTx {
405 base: self.base.clone(),
406 };
407 SerialParts::new(self, irq, emergency_tx)
408 }
409}
410
411impl<T: Kind> PollingUart for Ns16550<T> {
412 fn poll_status(&mut self) -> SerialEvent {
413 Ns16550::poll_status(self)
414 }
415
416 fn write_byte(&mut self, byte: u8) {
417 Ns16550::write_byte(self, byte);
418 }
419
420 fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
421 Ns16550::read_byte(self, status)
422 }
423}
424
425impl<T: Kind> Ns16550<T> {
426 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
428 F::from_bits_retain(self.base.read_reg(reg))
429 }
430
431 fn write_flags<F: Flags<Bits = u8>>(&mut self, reg: u8, val: F) {
432 self.base.write_reg(reg, val.bits());
433 }
434
435 pub fn pending(&mut self, direction: SerialDirection) -> bool {
436 let lsr = self.read_lsr_preserving();
437 match direction {
438 SerialDirection::Input => lsr.contains(LineStatusFlags::DATA_READY),
439 SerialDirection::Output => lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY),
440 }
441 }
442
443 pub fn poll_status(&mut self) -> SerialEvent {
444 serial_event_from_lsr(self.read_lsr_preserving())
445 }
446
447 pub fn try_write(&mut self, bytes: &[u8]) -> usize {
448 let mut written = 0;
449 while written < bytes.len() {
450 let status = self.poll_status();
451 if !status.tx_ready() {
452 break;
453 }
454 self.write_byte(bytes[written]);
455 written += 1;
456 }
457 written
458 }
459
460 pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
461 let mut read_count = 0;
462 let mut first_error = None;
463 for byte in bytes.iter_mut() {
464 let status = self.poll_status();
465 if !status.rx_ready() && !status.rx_error() {
466 break;
467 }
468 let result = self.read_byte(status);
469 match result {
470 Some(Ok(b)) => {
471 *byte = b;
472 read_count += 1;
473 }
474 Some(Err(TransferError::Overrun(b))) => {
475 *byte = b;
476 read_count += 1;
477 first_error.get_or_insert(TransferError::Overrun(b));
478 }
479 Some(Err(e)) => {
480 first_error.get_or_insert(e);
481 }
482 None => break,
483 }
484 }
485 if let Some(kind) = first_error {
486 Err(TransBytesError {
487 bytes_transferred: read_count,
488 kind,
489 })
490 } else {
491 Ok(read_count)
492 }
493 }
494
495 pub fn write_byte(&mut self, byte: u8) {
496 self.base.write_reg(UART_THR, byte);
497 }
498
499 pub fn read_rx(&mut self) -> Option<RxSample> {
500 read_rx_sample(&self.base, &mut self.saved_lsr)
501 }
502
503 fn read_lsr_preserving(&mut self) -> LineStatusFlags {
504 let lsr: LineStatusFlags = self.read_flags(UART_LSR);
505 self.saved_lsr
506 .insert(lsr & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
507 lsr | self.saved_lsr
508 }
509
510 pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
511 if !status.rx_ready() && !status.rx_error() {
512 return None;
513 }
514 if self.saved_lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
515 let b = self.base.read_reg(UART_RBR);
516 self.saved_lsr.remove(LineStatusFlags::OVERRUN_ERROR);
517 return Some(Err(TransferError::Overrun(b)));
518 }
519 if self.saved_lsr.contains(LineStatusFlags::PARITY_ERROR) {
520 let _ = self.base.read_reg(UART_RBR);
521 self.saved_lsr.remove(LineStatusFlags::PARITY_ERROR);
522 return Some(Err(TransferError::Parity));
523 }
524 if self.saved_lsr.contains(LineStatusFlags::FRAMING_ERROR) {
525 let _ = self.base.read_reg(UART_RBR);
526 self.saved_lsr.remove(LineStatusFlags::FRAMING_ERROR);
527 return Some(Err(TransferError::Framing));
528 }
529 if self.saved_lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
530 let _ = self.base.read_reg(UART_RBR);
531 self.saved_lsr.remove(LineStatusFlags::BREAK_INTERRUPT);
532 return Some(Err(TransferError::Break));
533 }
534 if status.rx_ready() {
535 return Some(Ok(self.base.read_reg(UART_RBR)));
536 }
537 None
538 }
539
540 pub fn open(&mut self) {
541 self.init_core();
542 }
543
544 pub fn close(&mut self) {
545 self.write_flags(UART_IER, InterruptEnableFlags::empty());
546
547 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
548 mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
549 self.write_flags(UART_MCR, mcr);
550 }
551
552 pub fn set_irq_mask(&mut self, events: SerialEventSet) {
553 self.write_flags(UART_IER, interrupt_enable_for_events(events));
554 }
555
556 pub fn get_irq_mask(&self) -> SerialEventSet {
557 let ier: InterruptEnableFlags = self.read_flags(UART_IER);
558 let mut events = SerialEventSet::empty();
559
560 if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
561 events |= SerialEventSet::RX_DATA;
562 }
563 if ier.contains(InterruptEnableFlags::RECEIVER_LINE_STATUS) {
564 events |= SerialEventSet::RX_STATUS;
565 }
566 if ier.contains(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY) {
567 events |= SerialEventSet::TX_SPACE;
568 }
569
570 events
571 }
572
573 pub fn is_16550_plus(&self) -> bool {
575 let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
578 fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
579 }
580
581 fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
583 self.base.set_baudrate(self.clock_freq, baudrate)
584 }
585
586 fn set_data_bits_internal(&mut self, bits: DataBits) -> Result<(), ConfigError> {
588 let wlen = match bits {
589 DataBits::Five => LineControlFlags::WORD_LENGTH_5,
590 DataBits::Six => LineControlFlags::WORD_LENGTH_6,
591 DataBits::Seven => LineControlFlags::WORD_LENGTH_7,
592 DataBits::Eight => LineControlFlags::WORD_LENGTH_8,
593 };
594
595 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
596 lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
598 lcr.insert(wlen);
599 self.write_flags(UART_LCR, lcr);
600
601 Ok(())
602 }
603
604 fn set_stop_bits_internal(&mut self, bits: StopBits) -> Result<(), ConfigError> {
606 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
607 match bits {
608 StopBits::One => lcr.remove(LineControlFlags::STOP_BITS),
609 StopBits::Two => lcr.insert(LineControlFlags::STOP_BITS),
610 }
611 self.write_flags(UART_LCR, lcr);
612 Ok(())
613 }
614
615 fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
617 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
618
619 lcr.remove(
621 LineControlFlags::PARITY_ENABLE
622 | LineControlFlags::EVEN_PARITY
623 | LineControlFlags::STICK_PARITY,
624 );
625
626 match parity {
628 Parity::None => {
629 }
631 Parity::Odd => {
632 lcr.insert(LineControlFlags::PARITY_ENABLE);
633 }
634 Parity::Even => {
635 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::EVEN_PARITY);
636 }
637 Parity::Mark => {
638 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::STICK_PARITY);
639 }
640 Parity::Space => {
641 lcr.insert(
642 LineControlFlags::PARITY_ENABLE
643 | LineControlFlags::EVEN_PARITY
644 | LineControlFlags::STICK_PARITY,
645 );
646 }
647 }
648
649 self.write_flags(UART_LCR, lcr);
650 Ok(())
651 }
652
653 pub fn enable_fifo(&mut self, enable: bool) {
655 if enable {
656 let mut fcr = FifoControlFlags::ENABLE_FIFO;
657 fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
658 fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
659 fcr.insert(FifoControlFlags::TRIGGER_8_BYTES);
663 self.write_flags(UART_FCR, fcr);
664 if self.is_fifo_enabled() {
665 return;
666 }
667 }
668 self.write_flags(UART_FCR, FifoControlFlags::empty());
669 }
670
671 pub fn set_fifo_trigger_level(&mut self, level: u8) {
673 if !self.is_16550_plus() {
674 return;
675 }
676
677 let trigger_value = match level {
678 0..=3 => FifoControlFlags::TRIGGER_1_BYTE,
679 4..=7 => FifoControlFlags::TRIGGER_4_BYTES,
680 8..=11 => FifoControlFlags::TRIGGER_8_BYTES,
681 _ => FifoControlFlags::TRIGGER_14_BYTES,
682 };
683
684 let mut fcr: FifoControlFlags = self.read_flags(UART_FCR);
686 fcr.remove(FifoControlFlags::TRIGGER_LEVEL_MASK);
687 fcr.insert(trigger_value);
688 self.write_flags(UART_FCR, fcr);
689 }
690
691 fn init_core(&mut self) {
693 self.base.init();
694 }
695
696 pub fn is_fifo_enabled(&self) -> bool {
698 if !self.is_16550_plus() {
699 return false;
700 }
701 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
703 iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
704 }
705}
706
707fn read_rx_sample<T: Kind>(base: &T, saved_lsr: &mut LineStatusFlags) -> Option<RxSample> {
708 let current: LineStatusFlags = base.read_flags(UART_LSR);
709 saved_lsr.insert(current & (LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR));
710 let lsr = current | *saved_lsr;
711 if !lsr.intersects(LineStatusFlags::DATA_READY | LineStatusFlags::ERROR_MASK) {
712 return None;
713 }
714
715 let byte = lsr
716 .contains(LineStatusFlags::DATA_READY)
717 .then(|| base.read_reg(UART_RBR));
718 let flag = if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
719 RxFlag::Break
720 } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
721 RxFlag::Parity
722 } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
723 RxFlag::Framing
724 } else {
725 RxFlag::Normal
726 };
727 let overrun = lsr.contains(LineStatusFlags::OVERRUN_ERROR);
728 saved_lsr.remove(LineStatusFlags::ERROR_MASK | LineStatusFlags::FIFO_ERROR);
729
730 Some(RxSample {
731 byte,
732 flag,
733 overrun,
734 })
735}
736
737fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
738 let mut errors = match sample.flag {
739 RxFlag::Normal => RxErrorFlags::empty(),
740 RxFlag::Break => RxErrorFlags::BREAK,
741 RxFlag::Parity => RxErrorFlags::PARITY,
742 RxFlag::Framing => RxErrorFlags::FRAMING,
743 };
744 if sample.overrun {
745 errors |= RxErrorFlags::OVERRUN;
746 }
747 errors
748}
749
750fn interrupt_enable_for_events(events: SerialEventSet) -> InterruptEnableFlags {
751 let mut ier = InterruptEnableFlags::empty();
752 if events.intersects(SerialEventSet::RX) {
753 ier.insert(
754 InterruptEnableFlags::RECEIVED_DATA_AVAILABLE
755 | InterruptEnableFlags::RECEIVER_LINE_STATUS,
756 );
757 }
758 if events.contains(SerialEventSet::TX_SPACE) {
759 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
760 }
761 ier
762}
763
764fn serial_event_from_lsr(lsr: LineStatusFlags) -> SerialEvent {
765 let mut event = SerialEvent::empty();
766 if lsr.contains(LineStatusFlags::DATA_READY) {
767 event |= SerialEvent::RX_READY;
768 }
769 if lsr.intersects(
770 LineStatusFlags::PARITY_ERROR
771 | LineStatusFlags::FRAMING_ERROR
772 | LineStatusFlags::BREAK_INTERRUPT,
773 ) {
774 event |= SerialEvent::RX_ERROR;
775 }
776 if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
777 event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
778 }
779 if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
780 event |= SerialEvent::TX_READY;
781 }
782 event
783}