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::Deque;
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: Deque<u8, 64>,
38    base: T,
39    clock_freq: u32,
40    is_tx_empty_int_enabled: bool,
41    err: Option<TransferError>,
42}
43
44impl<T: Kind> Ns16550<T> {
45    fn new(base: T, clock_freq: u32) -> Serial<Self> {
46        Serial::new(Self {
47            rcv_fifo: Deque::new(),
48            base,
49            clock_freq,
50            is_tx_empty_int_enabled: false,
51            err: None,
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
268            .rcv_fifo
269            .pop_front()
270            .expect("should check line status first"))
271    }
272
273    fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
274        // 配置波特率
275        if let Some(baudrate) = config.baudrate {
276            self.set_baudrate_internal(baudrate)?;
277        }
278
279        // 配置数据位
280        if let Some(data_bits) = config.data_bits {
281            self.set_data_bits_internal(data_bits)?;
282        }
283
284        // 配置停止位
285        if let Some(stop_bits) = config.stop_bits {
286            self.set_stop_bits_internal(stop_bits)?;
287        }
288
289        // 配置奇偶校验
290        if let Some(parity) = config.parity {
291            self.set_parity_internal(parity)?;
292        }
293
294        Ok(())
295    }
296
297    fn baudrate(&self) -> u32 {
298        // 只读方式获取波特率,通过读取 DLL 和 DLH
299        // 注意:如果 DLAB 未设置,读取的可能不是除数值
300        let dll = self.read_reg_u8(UART_DLL) as u16;
301        let dlh = self.read_reg_u8(UART_DLH) as u16;
302        let divisor = dll | (dlh << 8);
303
304        if divisor == 0 {
305            return 0;
306        }
307
308        self.clock_freq / (16 * divisor as u32)
309    }
310
311    fn data_bits(&self) -> DataBits {
312        let lcr: LineControlFlags = self.read_flags(UART_LCR);
313        let wlen = lcr & LineControlFlags::WORD_LENGTH_MASK;
314        if wlen == LineControlFlags::WORD_LENGTH_5 {
315            DataBits::Five
316        } else if wlen == LineControlFlags::WORD_LENGTH_6 {
317            DataBits::Six
318        } else if wlen == LineControlFlags::WORD_LENGTH_7 {
319            DataBits::Seven
320        } else {
321            DataBits::Eight // 默认值
322        }
323    }
324
325    fn stop_bits(&self) -> StopBits {
326        let lcr: LineControlFlags = self.read_flags(UART_LCR);
327        if lcr.contains(LineControlFlags::STOP_BITS) {
328            StopBits::Two
329        } else {
330            StopBits::One
331        }
332    }
333
334    fn parity(&self) -> Parity {
335        let lcr: LineControlFlags = self.read_flags(UART_LCR);
336
337        if !lcr.contains(LineControlFlags::PARITY_ENABLE) {
338            Parity::None
339        } else if lcr.contains(LineControlFlags::STICK_PARITY) {
340            // Stick parity
341            if lcr.contains(LineControlFlags::EVEN_PARITY) {
342                Parity::Space
343            } else {
344                Parity::Mark
345            }
346        } else {
347            // Normal parity
348            if lcr.contains(LineControlFlags::EVEN_PARITY) {
349                Parity::Even
350            } else {
351                Parity::Odd
352            }
353        }
354    }
355
356    fn open(&mut self) {
357        self.init();
358    }
359
360    fn close(&mut self) {
361        // 禁用所有中断
362        self.write_flags(UART_IER, InterruptEnableFlags::empty());
363
364        // 禁用 DTR 和 RTS
365        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
366        mcr.remove(ModemControlFlags::DATA_TERMINAL_READY | ModemControlFlags::REQUEST_TO_SEND);
367        self.write_flags(UART_MCR, mcr);
368    }
369
370    fn clean_interrupt_status(&mut self) -> InterruptMask {
371        let iir: InterruptIdentificationFlags = self.read_flags(UART_IIR);
372        let mut mask = InterruptMask::empty();
373
374        // 检查是否有中断挂起
375        if iir.contains(InterruptIdentificationFlags::NO_INTERRUPT_PENDING) {
376            return mask;
377        }
378
379        // 获取中断ID(需要提取bit 1-3)
380        let interrupt_id = iir & InterruptIdentificationFlags::INTERRUPT_ID_MASK;
381
382        // 使用精确匹配而不是 contains
383        if interrupt_id == InterruptIdentificationFlags::RECEIVER_LINE_STATUS {
384            // 接收线路状态错误中断
385            let lsr: LineStatusFlags = self.read_flags(UART_LSR);
386
387            // 读取 RBR 以清除错误状态(即使有错误也需要读取)
388            let d = self.read_reg_u8(UART_RBR);
389
390            // 按优先级检查错误(从高到低)
391            if lsr.contains(LineStatusFlags::OVERRUN_ERROR) {
392                self.err = Some(TransferError::Overrun(d));
393                mask |= InterruptMask::RX_AVAILABLE;
394            } else if lsr.contains(LineStatusFlags::PARITY_ERROR) {
395                self.err = Some(TransferError::Parity);
396                mask |= InterruptMask::RX_AVAILABLE;
397            } else if lsr.contains(LineStatusFlags::FRAMING_ERROR) {
398                self.err = Some(TransferError::Framing);
399                mask |= InterruptMask::RX_AVAILABLE;
400            } else if lsr.contains(LineStatusFlags::BREAK_INTERRUPT) {
401                self.err = Some(TransferError::Break);
402                mask |= InterruptMask::RX_AVAILABLE;
403            } else if lsr.contains(LineStatusFlags::DATA_READY) {
404                // 没有错误,保存数据到 FIFO
405                if self.rcv_fifo.push_back(d).is_err() {
406                    self.err = Some(TransferError::Overrun(d));
407                }
408                mask |= InterruptMask::RX_AVAILABLE;
409            }
410        } else if interrupt_id == InterruptIdentificationFlags::RECEIVED_DATA_AVAILABLE
411            || interrupt_id == InterruptIdentificationFlags::CHARACTER_TIMEOUT
412        {
413            // 接收数据可用中断或字符超时中断
414            mask |= InterruptMask::RX_AVAILABLE;
415
416            // 读取所有可用数据
417            while self
418                .read_flags::<LineStatusFlags>(UART_LSR)
419                .contains(LineStatusFlags::DATA_READY)
420            {
421                let d = self.read_reg_u8(UART_RBR);
422                if self.rcv_fifo.push_back(d).is_err() {
423                    self.err = Some(TransferError::Overrun(d));
424                    break;
425                }
426            }
427        } else if interrupt_id == InterruptIdentificationFlags::TRANSMITTER_HOLDING_EMPTY {
428            // 发送保持寄存器空中断
429            // 关闭 THRI 使能位,避免持续触发中断
430            // 用户在 write_byte 时会重新启用
431            let mut ier: InterruptEnableFlags = self.read_flags(UART_IER);
432            ier.remove(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
433            self.write_flags(UART_IER, ier);
434            if self.is_tx_empty_int_enabled {
435                mask |= InterruptMask::TX_EMPTY;
436            }
437        } else if interrupt_id == InterruptIdentificationFlags::MODEM_STATUS {
438            // Modem 状态中断,读取 MSR 清除
439            let _ = self.read_flags::<ModemStatusFlags>(UART_MSR);
440        }
441
442        mask
443    }
444
445    fn line_status(&mut self) -> LineStatus {
446        let lsr: LineStatusFlags = self.read_flags(UART_LSR);
447        let mut status = LineStatus::empty();
448        if self.err.is_some() {
449            status |= LineStatus::DATA_READY;
450        }
451
452        if lsr.contains(LineStatusFlags::TRANSMITTER_HOLDING_EMPTY) {
453            status |= LineStatus::TX_HOLDING_EMPTY;
454        }
455
456        if !self
457            .read_flags::<InterruptEnableFlags>(UART_IER)
458            .contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE)
459        {
460            // 如果未启用接收中断,则直接检查 LSR 的 DATA_READY 位
461            if lsr.contains(LineStatusFlags::DATA_READY) {
462                let b = self.read_reg_u8(UART_RBR);
463                if self.rcv_fifo.push_back(b).is_err() {
464                    self.err = Some(TransferError::Overrun(b));
465                }
466            }
467        }
468        // 检查 FIFO 中是否有数据
469        if !self.rcv_fifo.is_empty() {
470            status |= LineStatus::DATA_READY;
471        }
472
473        status
474    }
475
476    fn read_reg(&self, offset: usize) -> u32 {
477        self.read_reg_u8(offset as u8) as u32
478    }
479
480    fn write_reg(&mut self, offset: usize, value: u32) {
481        self.write_reg_u8(offset as u8, value as u8);
482    }
483
484    fn get_base(&self) -> usize {
485        self.base.get_base()
486    }
487
488    fn set_base(&mut self, base: usize) {
489        self.base.set_base(base);
490    }
491
492    fn clock_freq(&self) -> u32 {
493        self.clock_freq
494    }
495
496    fn enable_loopback(&mut self) {
497        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
498        mcr.insert(ModemControlFlags::LOOPBACK_ENABLE);
499        self.write_flags(UART_MCR, mcr);
500    }
501
502    fn disable_loopback(&mut self) {
503        let mut mcr: ModemControlFlags = self.read_flags(UART_MCR);
504        mcr.remove(ModemControlFlags::LOOPBACK_ENABLE);
505        self.write_flags(UART_MCR, mcr);
506    }
507
508    fn is_loopback_enabled(&self) -> bool {
509        let mcr: ModemControlFlags = self.read_flags(UART_MCR);
510        mcr.contains(ModemControlFlags::LOOPBACK_ENABLE)
511    }
512
513    fn set_irq_mask(&mut self, mask: InterruptMask) {
514        let mut ier = InterruptEnableFlags::empty();
515        self.is_tx_empty_int_enabled = false;
516
517        if mask.contains(InterruptMask::RX_AVAILABLE) {
518            ier.insert(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE);
519            ier.insert(InterruptEnableFlags::RECEIVER_LINE_STATUS);
520        }
521        if mask.contains(InterruptMask::TX_EMPTY) {
522            ier.insert(InterruptEnableFlags::TRANSMITTER_HOLDING_EMPTY);
523            self.is_tx_empty_int_enabled = true;
524        }
525
526        self.write_flags(UART_IER, ier);
527    }
528
529    fn get_irq_mask(&self) -> InterruptMask {
530        let ier: InterruptEnableFlags = self.read_flags(UART_IER);
531        let mut mask = InterruptMask::empty();
532
533        if ier.contains(InterruptEnableFlags::RECEIVED_DATA_AVAILABLE) {
534            mask |= InterruptMask::RX_AVAILABLE;
535        }
536        if self.is_tx_empty_int_enabled {
537            mask |= InterruptMask::TX_EMPTY;
538        }
539        // 错误中断暂不映射到 InterruptMask
540        // 用户需要通过状态寄存器检查错误
541
542        mask
543    }
544}