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