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