Skip to main content

some_serial/ns16550/
mod.rs

1//! NS16550/16450 UART 驱动模块
2//!
3//! 提供两种访问方式:
4//! - IO Port 版本(x86_64 架构)
5//! - MMIO 版本(通用嵌入式平台)
6
7// 公共寄存器定义
8mod 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
17#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
18mod pio;
19// MMIO 版本(通用)
20mod mmio;
21
22pub use mmio::*;
23#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
24pub use pio::*;
25
26use crate::{RawReciever, RawSender};
27
28pub trait Kind: Clone + Send + Sync + 'static {
29    fn read_reg(&self, reg: u8) -> u8;
30    fn write_reg(&self, reg: u8, val: u8);
31    fn get_base(&self) -> usize;
32
33    // 类型安全的 bitflags 寄存器访问
34    fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
35        F::from_bits_retain(self.read_reg(reg))
36    }
37
38    fn write_flags<F: Flags<Bits = u8>>(&self, reg: u8, val: F) {
39        self.write_reg(reg, val.bits());
40    }
41}
42
43pub struct Ns16550<T: Kind> {
44    pub(crate) base: T,
45    pub(crate) clock_freq: u32,
46    pub(crate) irq: Option<Ns16550IrqHandler<T>>,
47    pub(crate) tx: Option<crate::Sender>,
48    pub(crate) rx: Option<crate::Reciever>,
49}
50
51impl<T: Kind> InterfaceRaw for Ns16550<T> {
52    type Sender = crate::Sender;
53    type Reciever = crate::Reciever;
54    type IrqHandler = Ns16550IrqHandler<T>;
55
56    fn name(&self) -> &str {
57        "NS16550 UART"
58    }
59
60    fn base_addr(&self) -> usize {
61        self.base.get_base()
62    }
63
64    fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
65        // 配置波特率
66        if let Some(baudrate) = config.baudrate {
67            self.set_baudrate_internal(baudrate)?;
68        }
69
70        // 配置数据位
71        if let Some(data_bits) = config.data_bits {
72            self.set_data_bits_internal(data_bits)?;
73        }
74
75        // 配置停止位
76        if let Some(stop_bits) = config.stop_bits {
77            self.set_stop_bits_internal(stop_bits)?;
78        }
79
80        // 配置奇偶校验
81        if let Some(parity) = config.parity {
82            self.set_parity_internal(parity)?;
83        }
84        Ok(())
85    }
86
87    fn baudrate(&self) -> u32 {
88        // 只读方式获取波特率,通过读取 DLL 和 DLH
89        // 注意:如果 DLAB 未设置,读取的可能不是除数值
90        let dll = self.read_reg_u8(UART_DLL) as u16;
91        let dlh = self.read_reg_u8(UART_DLH) as u16;
92        let divisor = dll | (dlh << 8);
93
94        if divisor == 0 {
95            return 0;
96        }
97
98        self.clock_freq / (16 * divisor as u32)
99    }
100
101    fn data_bits(&self) -> DataBits {
102        let lcr: LineControlFlags = self.read_flags(UART_LCR);
103        let wlen = lcr & LineControlFlags::WORD_LENGTH_MASK;
104        if wlen == LineControlFlags::WORD_LENGTH_5 {
105            DataBits::Five
106        } else if wlen == LineControlFlags::WORD_LENGTH_6 {
107            DataBits::Six
108        } else if wlen == LineControlFlags::WORD_LENGTH_7 {
109            DataBits::Seven
110        } else {
111            DataBits::Eight // 默认值
112        }
113    }
114
115    fn stop_bits(&self) -> StopBits {
116        let lcr: LineControlFlags = self.read_flags(UART_LCR);
117        if lcr.contains(LineControlFlags::STOP_BITS) {
118            StopBits::Two
119        } else {
120            StopBits::One
121        }
122    }
123
124    fn parity(&self) -> Parity {
125        let lcr: LineControlFlags = self.read_flags(UART_LCR);
126
127        if !lcr.contains(LineControlFlags::PARITY_ENABLE) {
128            Parity::None
129        } else if lcr.contains(LineControlFlags::STICK_PARITY) {
130            // Stick parity
131            if lcr.contains(LineControlFlags::EVEN_PARITY) {
132                Parity::Space
133            } else {
134                Parity::Mark
135            }
136        } else {
137            // Normal parity
138            if lcr.contains(LineControlFlags::EVEN_PARITY) {
139                Parity::Even
140            } else {
141                Parity::Odd
142            }
143        }
144    }
145
146    fn clock_freq(&self) -> Option<core::num::NonZeroU32> {
147        self.clock_freq.try_into().ok()
148    }
149
150    fn open(&mut self) {
151        self.init();
152    }
153
154    fn close(&mut self) {
155        // 禁用所有中断
156        self.write_flags(UART_IER, InterruptEnableFlags::empty());
157
158        // 禁用 DTR 和 RTS
159        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
160        mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
161        self.write_flags(UART_MCR, mcr);
162    }
163
164    fn enable_loopback(&mut self) {
165        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
166        mcr.insert(ModemControlFlags::LOOPBACK_ENABLE);
167        self.write_flags(UART_MCR, mcr);
168    }
169
170    fn disable_loopback(&mut self) {
171        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
172        mcr.remove(ModemControlFlags::LOOPBACK_ENABLE);
173        self.write_flags(UART_MCR, mcr);
174    }
175
176    fn is_loopback_enabled(&self) -> bool {
177        let mcr: ModemControlFlags = self.read_flags(UART_MCR);
178        mcr.contains(ModemControlFlags::LOOPBACK_ENABLE)
179    }
180
181    fn set_irq_mask(&mut self, mask: InterruptMask) {
182        let mut ier = InterruptEnableFlags::empty();
183
184        if mask.contains(InterruptMask::RX_AVAILABLE) {
185            ier.insert(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE);
186            ier.insert(InterruptEnableFlags::RECEIVER_LINE_STATUS);
187        }
188        if mask.contains(InterruptMask::TX_EMPTY) {
189            ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
190        }
191
192        self.write_flags(UART_IER, ier);
193    }
194
195    fn get_irq_mask(&self) -> InterruptMask {
196        let ier: InterruptEnableFlags = self.read_flags(UART_IER);
197        let mut mask = InterruptMask::empty();
198
199        if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
200            mask |= InterruptMask::RX_AVAILABLE;
201        }
202        if ier.contains(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY) {
203            mask |= InterruptMask::TX_EMPTY;
204        }
205        // 错误中断暂不映射到 InterruptMask
206        // 用户需要通过状态寄存器检查错误
207
208        mask
209    }
210
211    fn irq_handler(&mut self) -> Option<Self::IrqHandler> {
212        self.irq.take()
213    }
214
215    fn take_tx(&mut self) -> Option<Self::Sender> {
216        self.tx.take()
217    }
218
219    fn take_rx(&mut self) -> Option<Self::Reciever> {
220        self.rx.take()
221    }
222
223    fn set_tx(&mut self, tx: Self::Sender) -> Result<(), SetBackError> {
224        let want = self.base.get_base();
225        match tx {
226            #[cfg(target_arch = "x86_64")]
227            crate::Sender::Ns16550Sender(ref sender) => {
228                let actual = sender.base.get_base();
229                if actual != want {
230                    return Err(SetBackError::new(want, actual));
231                }
232            }
233            crate::Sender::Ns16550MmioSender(ref sender) => {
234                let actual = sender.base.get_base();
235                if actual != want {
236                    return Err(SetBackError::new(want, actual));
237                }
238            }
239            _ => {
240                return Err(SetBackError::new(want, 0)); // 不匹配的类型
241            }
242        }
243        self.tx = Some(tx);
244        Ok(())
245    }
246
247    fn set_rx(&mut self, rx: Self::Reciever) -> Result<(), SetBackError> {
248        let want = self.base.get_base();
249        match rx {
250            #[cfg(target_arch = "x86_64")]
251            crate::Reciever::Ns16550Reciever(ref reciever) => {
252                let actual = reciever.base.get_base();
253                if actual != want {
254                    return Err(SetBackError::new(want, actual));
255                }
256            }
257            crate::Reciever::Ns16550MmioReciever(ref reciever) => {
258                let actual = reciever.base.get_base();
259                if actual != want {
260                    return Err(SetBackError::new(want, actual));
261                }
262            }
263            _ => {
264                return Err(SetBackError::new(want, 0)); // 不匹配的类型
265            }
266        }
267        self.rx = Some(rx);
268        Ok(())
269    }
270}
271
272impl<T: Kind> Ns16550<T> {
273    // 基础 u8 寄存器访问(用于除数寄存器等特殊场景)
274    fn read_reg_u8(&self, reg: u8) -> u8 {
275        self.base.read_reg(reg)
276    }
277
278    fn write_reg_u8(&mut self, reg: u8, val: u8) {
279        self.base.write_reg(reg, val);
280    }
281
282    // 类型安全的 bitflags 寄存器访问
283    fn read_flags<F: Flags<Bits = u8>>(&self, reg: u8) -> F {
284        F::from_bits_retain(self.base.read_reg(reg))
285    }
286
287    fn write_flags<F: Flags<Bits = u8>>(&mut self, reg: u8, val: F) {
288        self.base.write_reg(reg, val.bits());
289    }
290
291    /// 检查是否为 16550+(支持 FIFO)
292    pub fn is_16550_plus(&self) -> bool {
293        // 通过读取 IIR 寄存器的 FIFO 位来判断
294        // IIR 的位7-6在 16550+ 中会显示 FIFO 启用状态
295        let fifo: InterruptIdentificationFlags = self.read_flags(UART_IIR);
296        fifo.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
297    }
298
299    /// 设置波特率
300    fn set_baudrate_internal(&mut self, baudrate: u32) -> Result<(), ConfigError> {
301        if baudrate == 0 || self.clock_freq == 0 {
302            return Err(ConfigError::InvalidBaudrate);
303        }
304
305        let divisor = self.clock_freq / (16 * baudrate);
306        if divisor == 0 || divisor > 0xFFFF {
307            return Err(ConfigError::InvalidBaudrate);
308        }
309
310        // 保存原始 LCR
311        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
312
313        // 设置 DLAB 以访问波特率除数寄存器
314        lcr.insert(LineControlFlags::DIVISOR_LATCH_ACCESS);
315        self.write_flags(UART_LCR, lcr);
316
317        // 设置除数(使用 u8 方法,因为这是原始数据写入)
318        self.write_reg_u8(UART_DLL, (divisor & 0xFF) as u8);
319        self.write_reg_u8(UART_DLH, ((divisor >> 8) & 0xFF) as u8);
320
321        // 清除 DLAB 位,恢复正常访问
322        lcr.remove(LineControlFlags::DIVISOR_LATCH_ACCESS);
323        self.write_flags(UART_LCR, lcr);
324
325        Ok(())
326    }
327
328    /// 设置数据位
329    fn set_data_bits_internal(&mut self, bits: DataBits) -> Result<(), ConfigError> {
330        let wlen = match bits {
331            DataBits::Five => LineControlFlags::WORD_LENGTH_5,
332            DataBits::Six => LineControlFlags::WORD_LENGTH_6,
333            DataBits::Seven => LineControlFlags::WORD_LENGTH_7,
334            DataBits::Eight => LineControlFlags::WORD_LENGTH_8,
335        };
336
337        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
338        // 清除旧的数据位设置,然后设置新的
339        lcr.remove(LineControlFlags::WORD_LENGTH_MASK);
340        lcr.insert(wlen);
341        self.write_flags(UART_LCR, lcr);
342
343        Ok(())
344    }
345
346    /// 设置停止位
347    fn set_stop_bits_internal(&mut self, bits: StopBits) -> Result<(), ConfigError> {
348        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
349        match bits {
350            StopBits::One => lcr.remove(LineControlFlags::STOP_BITS),
351            StopBits::Two => lcr.insert(LineControlFlags::STOP_BITS),
352        }
353        self.write_flags(UART_LCR, lcr);
354        Ok(())
355    }
356
357    /// 设置奇偶校验
358    fn set_parity_internal(&mut self, parity: Parity) -> Result<(), ConfigError> {
359        let mut lcr: LineControlFlags = self.read_flags(UART_LCR);
360
361        // 先清除所有校验相关位
362        lcr.remove(
363            LineControlFlags::PARITY_ENABLE
364                | LineControlFlags::EVEN_PARITY
365                | LineControlFlags::STICK_PARITY,
366        );
367
368        // 根据校验类型设置相应位
369        match parity {
370            Parity::None => {
371                // 已经清除,无需额外操作
372            }
373            Parity::Odd => {
374                lcr.insert(LineControlFlags::PARITY_ENABLE);
375            }
376            Parity::Even => {
377                lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::EVEN_PARITY);
378            }
379            Parity::Mark => {
380                lcr.insert(LineControlFlags::PARITY_ENABLE | LineControlFlags::STICK_PARITY);
381            }
382            Parity::Space => {
383                lcr.insert(
384                    LineControlFlags::PARITY_ENABLE
385                        | LineControlFlags::EVEN_PARITY
386                        | LineControlFlags::STICK_PARITY,
387                );
388            }
389        }
390
391        self.write_flags(UART_LCR, lcr);
392        Ok(())
393    }
394
395    /// 启用或禁用 FIFO
396    pub fn enable_fifo(&mut self, enable: bool) {
397        if enable && self.is_16550_plus() {
398            let mut fcr = FifoControlFlags::ENABLE_FIFO;
399            fcr.insert(FifoControlFlags::CLEAR_RECEIVER_FIFO);
400            fcr.insert(FifoControlFlags::CLEAR_TRANSMITTER_FIFO);
401            fcr.insert(FifoControlFlags::TRIGGER_1_BYTE);
402            self.write_flags(UART_FCR, fcr);
403        } else {
404            self.write_flags(UART_FCR, FifoControlFlags::empty());
405        }
406    }
407
408    /// 设置 FIFO 触发级别
409    pub fn set_fifo_trigger_level(&mut self, level: u8) {
410        if !self.is_16550_plus() {
411            return;
412        }
413
414        let trigger_value = match level {
415            0..=3 => FifoControlFlags::TRIGGER_1_BYTE,
416            4..=7 => FifoControlFlags::TRIGGER_4_BYTES,
417            8..=11 => FifoControlFlags::TRIGGER_8_BYTES,
418            _ => FifoControlFlags::TRIGGER_14_BYTES,
419        };
420
421        // 读取当前 FCR 设置,清除触发级别位,然后设置新的触发级别
422        let mut fcr: FifoControlFlags = self.read_flags(UART_FCR);
423        fcr.remove(FifoControlFlags::TRIGGER_LEVEL_MASK);
424        fcr.insert(trigger_value);
425        self.write_flags(UART_FCR, fcr);
426    }
427
428    /// 初始化 UART
429    fn init(&mut self) {
430        // 禁用所有中断
431        self.write_flags(UART_IER, InterruptEnableFlags::empty());
432
433        // 确保传输器启用(设置 DTR 和 RTS)
434        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
435        mcr.insert(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
436        self.write_flags(UART_MCR, mcr);
437    }
438
439    /// 检查 FIFO 是否启用
440    pub fn is_fifo_enabled(&self) -> bool {
441        if !self.is_16550_plus() {
442            return false;
443        }
444        // 通过检查 IIR 的 FIFO 位来判断
445        let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
446        iir.contains(InterruptIdentificationFlags::FIFO_ENABLE_MASK)
447    }
448}
449
450pub struct Ns16550Sender<T: Kind> {
451    pub(crate) base: T,
452}
453
454impl<T: Kind> TSender for Ns16550Sender<T> {
455    fn write_byte(&mut self, byte: u8) -> bool {
456        RawSender::write_byte(self, byte)
457    }
458}
459
460pub struct Ns16550Reciever<T: Kind> {
461    pub(crate) base: T,
462}
463
464impl<T: Kind> RawReciever for Ns16550Reciever<T> {
465    fn read_byte(&mut self) -> Option<Result<u8, TransferError>> {
466        let lsr: LineStatusFlags = self.base.read_flags(UART_LSR);
467
468        // 按优先级检查错误(从高到低)
469        if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
470            let b = self.base.read_reg(UART_RBR);
471            return Some(Err(TransferError::Overrun(b)));
472        }
473
474        if lsr.contains(LineStatusFlags::PARITY_ERROR) {
475            let _b = self.base.read_reg(UART_RBR);
476            return Some(Err(TransferError::Parity));
477        }
478
479        if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
480            let _b = self.base.read_reg(UART_RBR);
481            return Some(Err(TransferError::Framing));
482        }
483
484        if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
485            let _b = self.base.read_reg(UART_RBR);
486            return Some(Err(TransferError::Break));
487        }
488
489        if lsr.contains(LineStatusFlags::DATA_READY) {
490            let b = self.base.read_reg(UART_RBR);
491            return Some(Ok(b));
492        }
493        None
494    }
495}
496
497pub struct Ns16550IrqHandler<T: Kind> {
498    pub(crate) base: T,
499}
500
501impl<T: Kind> TIrqHandler for Ns16550IrqHandler<T> {
502    fn clean_interrupt_status(&self) -> InterruptMask {
503        let iir: InterruptIdentificationFlags = self.base.read_flags(UART_IIR);
504        let mut mask = InterruptMask::empty();
505
506        // 检查是否有中断挂起
507        if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
508            return mask;
509        }
510
511        // 获取中断ID(需要提取bit 1-3)
512        let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
513
514        // 使用精确匹配而不是 contains
515        if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS
516            || interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE
517            || interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT
518        {
519            // 接收数据可用中断或字符超时中断
520            mask |= InterruptMask::RX_AVAILABLE;
521        } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
522            // 发送保持寄存器空中断
523            mask |= InterruptMask::TX_EMPTY;
524        } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
525            // Modem 状态中断
526        }
527
528        mask
529    }
530}
531
532impl<T: Kind> RawSender for Ns16550Sender<T> {
533    fn write_byte(&mut self, byte: u8) -> bool {
534        let lsr: LineStatusFlags = self.base.read_flags(UART_LSR);
535        if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
536            self.base.write_reg(UART_THR, byte);
537            true
538        } else {
539            false
540        }
541    }
542}