Skip to main content

uart16550/
lib.rs

1//! Provide definition of 16550 uart registers.
2
3#![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
25/// 寄存器特质。
26///
27/// 由于 16550 设计历史悠久,它的实现有 8 位寄存器和 32 位寄存器两种模式,
28/// 在驱动中用这个特质来描述。但无论哪种模式,只要是兼容 16550 定义,就只有 8 位是有效的。
29pub trait Register: From<u8> {
30    /// 取出寄存器中的有效位。
31    fn val(self) -> u8;
32}
33
34/// 寄存器的 8 位模式。
35impl Register for u8 {
36    #[inline]
37    fn val(self) -> u8 {
38        self
39    }
40}
41
42/// 寄存器的 32 位模式。
43impl Register for u32 {
44    #[inline]
45    fn val(self) -> u8 {
46        self as _
47    }
48}
49
50/// 接收缓冲寄存器和发送保持寄存器。
51#[allow(non_camel_case_types)]
52#[repr(transparent)]
53pub struct RBR_THR<R: Register>(UnsafeCell<R>);
54
55/// 中断使能寄存器。
56#[repr(transparent)]
57pub struct IER<R: Register>(UnsafeCell<R>);
58
59/// 中断识别寄存器和队列控制寄存器。
60#[allow(non_camel_case_types)]
61#[repr(transparent)]
62pub struct IIR_FCR<R: Register>(UnsafeCell<R>);
63
64/// 线路控制寄存器。
65#[repr(transparent)]
66pub struct LCR<R: Register>(UnsafeCell<R>);
67
68/// 调制解调器控制寄存器。
69#[repr(transparent)]
70pub struct MCR<R: Register>(UnsafeCell<R>);
71
72/// 线路状态寄存器。
73#[repr(transparent)]
74pub struct LSR<R: Register>(UnsafeCell<R>);
75
76/// 调制解调器状态寄存器。
77#[repr(transparent)]
78pub struct MSR<R: Register>(UnsafeCell<R>);
79
80/// 工作状态的 uart16550 数据结构。
81#[repr(C)]
82pub struct Uart16550<R: Register> {
83    rbr_thr: RBR_THR<R>, // offset = 0(0x00)
84    ier: IER<R>,         // offset = 1(0x04)
85    iir_fcr: IIR_FCR<R>, // offset = 2(0x08)
86    lcr: LCR<R>,         // offset = 3(0x0c)
87    mcr: MCR<R>,         // offset = 4(0x10)
88    lsr: LSR<R>,         // offset = 5(0x14)
89    msr: MSR<R>,         // offset = 6(0x18)
90}
91
92impl<R: Register> Uart16550<R> {
93    /// 取出接收缓冲和发送保持寄存器。
94    #[inline]
95    pub fn rbr_thr(&self) -> &RBR_THR<R> {
96        &self.rbr_thr
97    }
98
99    /// 取出中断使能寄存器。
100    #[inline]
101    pub fn ier(&self) -> &IER<R> {
102        &self.ier
103    }
104
105    /// 取出中断识别和队列控制寄存器。
106    #[inline]
107    pub fn iir_fcr(&self) -> &IIR_FCR<R> {
108        &self.iir_fcr
109    }
110
111    /// 取出线路控制寄存器。
112    #[inline]
113    pub fn lcr(&self) -> &LCR<R> {
114        &self.lcr
115    }
116
117    /// 取出调制解调器控制寄存器。
118    #[inline]
119    pub fn mcr(&self) -> &MCR<R> {
120        &self.mcr
121    }
122
123    /// 取出线路状态寄存器。
124    #[inline]
125    pub fn lsr(&self) -> &LSR<R> {
126        &self.lsr
127    }
128
129    /// 取出调制解调器状态寄存器。
130    #[inline]
131    pub fn msr(&self) -> &MSR<R> {
132        &self.msr
133    }
134
135    /// 将分频系数写入锁存器。
136    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    /// 从接收队列读取字符到 `buf`,返回读取的字符数。
147    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    /// 从 `buf` 写入字符到发送队列,返回写入的字符数。
161    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}