1#![no_std]
4#![deny(warnings, missing_docs)]
5
6mod fcr;
7mod ier;
8mod iir;
9mod lcr;
10mod lsr;
11mod mcr;
12mod msr;
13mod rbr_thr;
14
15use core::cell::UnsafeCell;
16
17pub use fcr::{FifoControl, TriggerLevel};
18pub use ier::InterruptTypes;
19pub use iir::{InterruptIdentification, PendingInterrupt};
20pub use lcr::{CharLen, LineControl, PARITY};
21pub use lsr::LineStatus;
22pub use mcr::ModemControl;
23pub use msr::ModemStatus;
24
25pub trait Register: From<u8> {
30 fn val(self) -> u8;
32}
33
34impl Register for u8 {
36 #[inline]
37 fn val(self) -> u8 {
38 self
39 }
40}
41
42impl Register for u32 {
44 #[inline]
45 fn val(self) -> u8 {
46 self as _
47 }
48}
49
50#[allow(non_camel_case_types)]
52#[repr(transparent)]
53pub struct RBR_THR<R: Register>(UnsafeCell<R>);
54
55#[repr(transparent)]
57pub struct IER<R: Register>(UnsafeCell<R>);
58
59#[allow(non_camel_case_types)]
61#[repr(transparent)]
62pub struct IIR_FCR<R: Register>(UnsafeCell<R>);
63
64#[repr(transparent)]
66pub struct LCR<R: Register>(UnsafeCell<R>);
67
68#[repr(transparent)]
70pub struct MCR<R: Register>(UnsafeCell<R>);
71
72#[repr(transparent)]
74pub struct LSR<R: Register>(UnsafeCell<R>);
75
76#[repr(transparent)]
78pub struct MSR<R: Register>(UnsafeCell<R>);
79
80#[repr(C)]
82pub struct Uart16550<R: Register> {
83 rbr_thr: RBR_THR<R>, ier: IER<R>, iir_fcr: IIR_FCR<R>, lcr: LCR<R>, mcr: MCR<R>, lsr: LSR<R>, msr: MSR<R>, }
91
92impl<R: Register> Uart16550<R> {
93 #[inline]
95 pub fn rbr_thr(&self) -> &RBR_THR<R> {
96 &self.rbr_thr
97 }
98
99 #[inline]
101 pub fn ier(&self) -> &IER<R> {
102 &self.ier
103 }
104
105 #[inline]
107 pub fn iir_fcr(&self) -> &IIR_FCR<R> {
108 &self.iir_fcr
109 }
110
111 #[inline]
113 pub fn lcr(&self) -> &LCR<R> {
114 &self.lcr
115 }
116
117 #[inline]
119 pub fn mcr(&self) -> &MCR<R> {
120 &self.mcr
121 }
122
123 #[inline]
125 pub fn lsr(&self) -> &LSR<R> {
126 &self.lsr
127 }
128
129 #[inline]
131 pub fn msr(&self) -> &MSR<R> {
132 &self.msr
133 }
134
135 pub fn write_divisor(&self, divisor: u16) {
137 let lcr = self.lcr.read();
138 self.lcr.write(lcr.enable_dlr_access());
139 unsafe {
140 self.rbr_thr.0.get().write(R::from(divisor as _));
141 self.ier.0.get().write(R::from((divisor >> 8) as _));
142 }
143 self.lcr.write(lcr);
144 }
145
146 pub fn read(&self, buf: &mut [u8]) -> usize {
148 let mut count = 0usize;
149 for c in buf {
150 if self.lsr.read().is_data_ready() {
151 *c = self.rbr_thr.rx_data();
152 count += 1;
153 } else {
154 break;
155 }
156 }
157 count
158 }
159
160 pub fn write(&self, buf: &[u8]) -> usize {
162 let mut count = 0usize;
163 for c in buf {
164 if self.lsr.read().is_transmitter_fifo_empty() {
165 self.rbr_thr.tx_data(*c);
166 count += 1;
167 } else {
168 break;
169 }
170 }
171 count
172 }
173}