1mod registers;
9
10use bitflags::Flags;
11use rdif_serial::{
12 Config, ConfigError, DataBits, InterfaceRaw, InterruptMask, Parity, SetBackError, StopBits,
13 TIrqHandler, TSender, TransferError,
14};
15use registers::*;
16
17pub mod dw_apb;
18#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
19mod pio;
20pub mod rockchip_fiq;
21mod mmio;
23
24pub use dw_apb::*;
25pub use mmio::*;
26#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
27pub use pio::*;
28pub use rockchip_fiq::*;
29
30use crate::{RawReciever, RawSender};
31
32pub trait Kind: Clone + Send + Sync + 'static {
33 fn read_reg(&self, reg: u8) -> u8;
34 fn write_reg(&self, reg: u8, val: u8);
35 fn get_base(&self) -> usize;
36
37 fn set_baudrate(&self, clock_freq: u32, baudrate: u32) -> Result<(), ConfigError> {
38 if baudrate == 0 || clock_freq == 0 {
39 return Err(ConfigError::InvalidBaudrate);
40 }
41
42 let divisor = clock_freq / (16 * baudrate);
43 if divisor == 0 || divisor > 0xFFFF {
44 return Err(ConfigError::InvalidBaudrate);
45 }
46
47 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
48 lcr.insert(LineControlFlags::DIVISOR_LATCH_ACCESS);
49 self.write_flags(UART_LCR, lcr);
50
51 self.write_reg(UART_DLL, (divisor & 0xFF) as u8);
52 self.write_reg(UART_DLH, ((divisor >> 8) & 0xFF) as u8);
53
54 lcr.remove(LineControlFlags::DIVISOR_LATCH_ACCESS);
55 self.write_flags(UART_LCR, lcr);
56
57 Ok(())
58 }
59
60 fn baudrate(&self, clock_freq: u32) -> u32 {
61 let dll = self.read_reg(UART_DLL) as u16;
62 let dlh = self.read_reg(UART_DLH) as u16;
63 let divisor = dll | (dlh << 8);
64
65 if divisor == 0 {
66 return 0;
67 }
68
69 clock_freq / (16 * divisor as u32)
70 }
71
72 fn init(&self) {
73 self.write_flags(UART_IER, InterruptEnableFlags::empty());
74
75 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
76 mcr.insert(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
77 self.write_flags(UART_MCR, mcr);
78 }
79
80 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
82 F::from_bits_retain(self.read_reg(reg))
83 }
84
85 fn write_flags<F: Flags<Bits = u8>>(&self, reg: u8, val: F) {
86 self.write_reg(reg, val.bits());
87 }
88}
89
90pub struct Ns16550<T: Kind> {
91 pub(crate) base: T,
92 pub(crate) clock_freq: u32,
93 pub(crate) irq: Option<Ns16550IrqHandler<T>>,
94 pub(crate) tx: Option<crate::Sender>,
95 pub(crate) rx: Option<crate::Reciever>,
96}
97
98impl<T: Kind> InterfaceRaw for Ns16550<T> {
99 type Sender = crate::Sender;
100 type Reciever = crate::Reciever;
101 type IrqHandler = Ns16550IrqHandler<T>;
102
103 fn name(&self) -> &str {
104 "NS16550 UART"
105 }
106
107 fn base_addr(&self) -> usize {
108 self.base.get_base()
109 }
110
111 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
112 if let Some(baudrate) = config.baudrate {
114 self.set_baudrate_internal(baudrate)?;
115 }
116
117 if let Some(data_bits) = config.data_bits {
119 self.set_data_bits_internal(data_bits)?;
120 }
121
122 if let Some(stop_bits) = config.stop_bits {
124 self.set_stop_bits_internal(stop_bits)?;
125 }
126
127 if let Some(parity) = config.parity {
129 self.set_parity_internal(parity)?;
130 }
131 Ok(())
132 }
133
134 fn baudrate(&self) -> u32 {
135 self.base.baudrate(self.clock_freq)
136 }
137
138 fn data_bits(&self) -> DataBits {
139 let lcr: LineControlFlags = self.read_flags(UART_LCR);
140 let wlen = lcr & LineControlFlags::WORD_LENGTH_MASK;
141 if wlen == LineControlFlags::WORD_LENGTH_5 {
142 DataBits::Five
143 } else if wlen == LineControlFlags::WORD_LENGTH_6 {
144 DataBits::Six
145 } else if wlen == LineControlFlags::WORD_LENGTH_7 {
146 DataBits::Seven
147 } else {
148 DataBits::Eight }
150 }
151
152 fn stop_bits(&self) -> StopBits {
153 let lcr: LineControlFlags = self.read_flags(UART_LCR);
154 if lcr.contains(LineControlFlags::STOP_BITS) {
155 StopBits::Two
156 } else {
157 StopBits::One
158 }
159 }
160
161 fn parity(&self) -> Parity {
162 let lcr: LineControlFlags = self.read_flags(UART_LCR);
163
164 if !lcr.contains(LineControlFlags::PARITY_ENABLE) {
165 Parity::None
166 } else if lcr.contains(LineControlFlags::STICK_PARITY) {
167 if lcr.contains(LineControlFlags::EVEN_PARITY) {
169 Parity::Space
170 } else {
171 Parity::Mark
172 }
173 } else {
174 if lcr.contains(LineControlFlags::EVEN_PARITY) {
176 Parity::Even
177 } else {
178 Parity::Odd
179 }
180 }
181 }
182
183 fn clock_freq(&self) -> Option<core::num::NonZeroU32> {
184 self.clock_freq.try_into().ok()
185 }
186
187 fn open(&mut self) {
188 self.init_core();
189 }
190
191 fn close(&mut self) {
192 self.write_flags(UART_IER, InterruptEnableFlags::empty());
194
195 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
197 mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
198 self.write_flags(UART_MCR, mcr);
199 }
200
201 fn enable_loopback(&mut self) {
202 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
203 mcr.insert(ModemControlFlags::LOOPBACK_ENABLE);
204 self.write_flags(UART_MCR, mcr);
205 }
206
207 fn disable_loopback(&mut self) {
208 let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
209 mcr.remove(ModemControlFlags::LOOPBACK_ENABLE);
210 self.write_flags(UART_MCR, mcr);
211 }
212
213 fn is_loopback_enabled(&self) -> bool {
214 let mcr: ModemControlFlags = self.read_flags(UART_MCR);
215 mcr.contains(ModemControlFlags::LOOPBACK_ENABLE)
216 }
217
218 fn set_irq_mask(&mut self, mask: InterruptMask) {
219 let mut ier = InterruptEnableFlags::empty();
220
221 if mask.contains(InterruptMask::RX_AVAILABLE) {
222 ier.insert(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE);
223 ier.insert(InterruptEnableFlags::RECEIVER_LINE_STATUS);
224 }
225 if mask.contains(InterruptMask::TX_EMPTY) {
226 ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
227 }
228
229 self.write_flags(UART_IER, ier);
230 }
231
232 fn get_irq_mask(&self) -> InterruptMask {
233 let ier: InterruptEnableFlags = self.read_flags(UART_IER);
234 let mut mask = InterruptMask::empty();
235
236 if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
237 mask |= InterruptMask::RX_AVAILABLE;
238 }
239 if ier.contains(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY) {
240 mask |= InterruptMask::TX_EMPTY;
241 }
242 mask
246 }
247
248 fn irq_handler(&mut self) -> Option<Self::IrqHandler> {
249 self.irq.take()
250 }
251
252 fn take_tx(&mut self) -> Option<Self::Sender> {
253 self.tx.take()
254 }
255
256 fn take_rx(&mut self) -> Option<Self::Reciever> {
257 self.rx.take()
258 }
259
260 fn set_tx(&mut self, tx: Self::Sender) -> Result<(), SetBackError> {
261 let want = self.base.get_base();
262 match tx {
263 #[cfg(target_arch = "x86_64")]
264 crate::Sender::Ns16550Sender(ref sender) => {
265 let actual = sender.base.get_base();
266 if actual != want {
267 return Err(SetBackError::new(want, actual));
268 }
269 }
270 crate::Sender::Ns16550MmioSender(ref sender) => {
271 let actual = sender.base.get_base();
272 if actual != want {
273 return Err(SetBackError::new(want, actual));
274 }
275 }
276 crate::Sender::Ns16550DwApbSender(ref sender) => {
277 let actual = sender.base.get_base();
278 if actual != want {
279 return Err(SetBackError::new(want, actual));
280 }
281 }
282 crate::Sender::Ns16550RockchipFiqSender(ref sender) => {
283 let actual = sender.base_addr();
284 if actual != want {
285 return Err(SetBackError::new(want, actual));
286 }
287 }
288 _ => {
289 return Err(SetBackError::new(want, 0)); }
291 }
292 self.tx = Some(tx);
293 Ok(())
294 }
295
296 fn set_rx(&mut self, rx: Self::Reciever) -> Result<(), SetBackError> {
297 let want = self.base.get_base();
298 match rx {
299 #[cfg(target_arch = "x86_64")]
300 crate::Reciever::Ns16550Reciever(ref reciever) => {
301 let actual = reciever.base.get_base();
302 if actual != want {
303 return Err(SetBackError::new(want, actual));
304 }
305 }
306 crate::Reciever::Ns16550MmioReciever(ref reciever) => {
307 let actual = reciever.base.get_base();
308 if actual != want {
309 return Err(SetBackError::new(want, actual));
310 }
311 }
312 crate::Reciever::Ns16550DwApbReciever(ref reciever) => {
313 let actual = reciever.base.get_base();
314 if actual != want {
315 return Err(SetBackError::new(want, actual));
316 }
317 }
318 crate::Reciever::Ns16550RockchipFiqReciever(ref reciever) => {
319 let actual = reciever.base_addr();
320 if actual != want {
321 return Err(SetBackError::new(want, actual));
322 }
323 }
324 _ => {
325 return Err(SetBackError::new(want, 0)); }
327 }
328 self.rx = Some(rx);
329 Ok(())
330 }
331}
332
333impl<T: Kind> Ns16550<T> {
334 fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
336 F::from_bits_retain(self.base.read_reg(reg))
337 }
338
339 fn write_flags<F: Flags<Bits = u8>>(&mut self, reg: u8, val: F) {
340 self.base.write_reg(reg, val.bits());
341 }
342
343 pub fn is_16550_plus(&self) -> bool {
345 let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
348 fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
349 }
350
351 fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
353 self.base.set_baudrate(self.clock_freq, baudrate)
354 }
355
356 fn set_data_bits_internal(&mut self, bits: DataBits) -> Result<(), ConfigError> {
358 let wlen = match bits {
359 DataBits::Five => LineControlFlags::WORD_LENGTH_5,
360 DataBits::Six => LineControlFlags::WORD_LENGTH_6,
361 DataBits::Seven => LineControlFlags::WORD_LENGTH_7,
362 DataBits::Eight => LineControlFlags::WORD_LENGTH_8,
363 };
364
365 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
366 lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
368 lcr.insert(wlen);
369 self.write_flags(UART_LCR, lcr);
370
371 Ok(())
372 }
373
374 fn set_stop_bits_internal(&mut self, bits: StopBits) -> Result<(), ConfigError> {
376 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
377 match bits {
378 StopBits::One => lcr.remove(LineControlFlags::STOP_BITS),
379 StopBits::Two => lcr.insert(LineControlFlags::STOP_BITS),
380 }
381 self.write_flags(UART_LCR, lcr);
382 Ok(())
383 }
384
385 fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
387 let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
388
389 lcr.remove(
391 LineControlFlags::PARITY_ENABLE
392 | LineControlFlags::EVEN_PARITY
393 | LineControlFlags::STICK_PARITY,
394 );
395
396 match parity {
398 Parity::None => {
399 }
401 Parity::Odd => {
402 lcr.insert(LineControlFlags::PARITY_ENABLE);
403 }
404 Parity::Even => {
405 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::EVEN_PARITY);
406 }
407 Parity::Mark => {
408 lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::STICK_PARITY);
409 }
410 Parity::Space => {
411 lcr.insert(
412 LineControlFlags::PARITY_ENABLE
413 | LineControlFlags::EVEN_PARITY
414 | LineControlFlags::STICK_PARITY,
415 );
416 }
417 }
418
419 self.write_flags(UART_LCR, lcr);
420 Ok(())
421 }
422
423 pub fn enable_fifo(&mut self, enable: bool) {
425 if enable && self.is_16550_plus() {
426 let mut fcr = FifoControlFlags::ENABLE_FIFO;
427 fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
428 fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
429 fcr.insert(FifoControlFlags::TRIGGER_1_BYTE);
430 self.write_flags(UART_FCR, fcr);
431 } else {
432 self.write_flags(UART_FCR, FifoControlFlags::empty());
433 }
434 }
435
436 pub fn set_fifo_trigger_level(&mut self, level: u8) {
438 if !self.is_16550_plus() {
439 return;
440 }
441
442 let trigger_value = match level {
443 0..=3 => FifoControlFlags::TRIGGER_1_BYTE,
444 4..=7 => FifoControlFlags::TRIGGER_4_BYTES,
445 8..=11 => FifoControlFlags::TRIGGER_8_BYTES,
446 _ => FifoControlFlags::TRIGGER_14_BYTES,
447 };
448
449 let mut fcr: FifoControlFlags = self.read_flags(UART_FCR);
451 fcr.remove(FifoControlFlags::TRIGGER_LEVEL_MASK);
452 fcr.insert(trigger_value);
453 self.write_flags(UART_FCR, fcr);
454 }
455
456 fn init_core(&mut self) {
458 self.base.init();
459 }
460
461 pub fn is_fifo_enabled(&self) -> bool {
463 if !self.is_16550_plus() {
464 return false;
465 }
466 let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
468 iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
469 }
470}
471
472pub struct Ns16550Sender<T: Kind> {
473 pub(crate) base: T,
474}
475
476impl<T: Kind> TSender for Ns16550Sender<T> {
477 fn write_byte(&mut self, byte: u8) -> bool {
478 RawSender::write_byte(self, byte)
479 }
480}
481
482pub struct Ns16550Reciever<T: Kind> {
483 pub(crate) base: T,
484}
485
486impl<T: Kind> RawReciever for Ns16550Reciever<T> {
487 fn read_byte(&mut self) -> Option<Result<u8, TransferError>> {
488 let lsr: LineStatusFlags = self.base.read_flags(UART_LSR);
489
490 if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
492 let b = self.base.read_reg(UART_RBR);
493 return Some(Err(TransferError::Overrun(b)));
494 }
495
496 if lsr.contains(LineStatusFlags::PARITY_ERROR) {
497 let _b = self.base.read_reg(UART_RBR);
498 return Some(Err(TransferError::Parity));
499 }
500
501 if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
502 let _b = self.base.read_reg(UART_RBR);
503 return Some(Err(TransferError::Framing));
504 }
505
506 if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
507 let _b = self.base.read_reg(UART_RBR);
508 return Some(Err(TransferError::Break));
509 }
510
511 if lsr.contains(LineStatusFlags::DATA_READY) {
512 let b = self.base.read_reg(UART_RBR);
513 return Some(Ok(b));
514 }
515 None
516 }
517}
518
519pub struct Ns16550IrqHandler<T: Kind> {
520 pub(crate) base: T,
521}
522
523impl<T: Kind> TIrqHandler for Ns16550IrqHandler<T> {
524 fn clean_interrupt_status(&self) -> InterruptMask {
525 let iir: InterruptIdentificationFlags = self.base.read_flags(UART_IIR);
526 let mut mask = InterruptMask::empty();
527
528 if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
530 return mask;
531 }
532
533 let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
535
536 if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS
538 || interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE
539 || interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT
540 {
541 mask |= InterruptMask::RX_AVAILABLE;
543 } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
544 mask |= InterruptMask::TX_EMPTY;
546 } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
547 }
549
550 mask
551 }
552}
553
554impl<T: Kind> RawSender for Ns16550Sender<T> {
555 fn write_byte(&mut self, byte: u8) -> bool {
556 let lsr: LineStatusFlags = self.base.read_flags(UART_LSR);
557 if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
558 self.base.write_reg(UART_THR, byte);
559 true
560 } else {
561 false
562 }
563 }
564}