Skip to main content

some_serial/
lib.rs

1#![no_std]
2
3//! # Some Serial - 嵌入式串口驱动集合
4//!
5//! 本库提供统一的串口驱动接口,支持多种硬件平台:
6//! - ARM PL011 UART
7//! - NS16550/16450 UART(IO Port、MMIO 和 DesignWare APB 版本)
8//!
9//! ## 特性
10//!
11//! - 🏗️ 统一抽象接口 - 基于 `rdif-serial` 的统一串口抽象
12//! - 🛡️ 无标准库设计 (`no_std`) - 适用于裸机和嵌入式系统
13//! - 📦 模块化架构 - 每个驱动独立模块,按需选择
14//! - 🔒 类型安全 - 使用 Rust 类型系统确保内存安全
15//! - ⚡ 高性能 - 零拷贝数据传输,直接硬件访问
16//!
17//! ## 支持的驱动
18//!
19//! ### ARM PL011 UART
20//! - 广泛用于 ARM Cortex-A、Cortex-M、Cortex-R 系列
21//! - 支持 FIFO、中断、回环等完整功能
22//!
23//! ### NS16550/16450 UART
24//! - 经典 PC 串口控制器,广泛兼容
25//! - 支持 IO Port(x86_64)、MMIO(通用)和 DesignWare APB 访问方式
26//! - 支持 16 字节 FIFO 缓冲
27//!
28//! ## 快速开始
29//!
30//! ```rust
31//! use some_serial::pl011::Pl011; // ARM PL011
32//! use some_serial::{Config, Serial, ns16550::Ns16550Mmio}; // NS16550 MMIO
33//!
34//! // 选择合适的驱动
35//! #[cfg(target_arch = "aarch64")]
36//! let mut uart = Pl011::new(NonNull::new(0x9000000 as *mut u8).unwrap(), 24_000_000);
37//!
38//! #[cfg(not(target_arch = "aarch64"))]
39//! let mut uart = Ns16550Mmio::new(NonNull::new(0x9000000 as *mut u8).unwrap(), 1_843_200);
40//!
41//! // 配置串口
42//! let config = Config::new()
43//!     .baudrate(115200)
44//!     .data_bits(some_serial::DataBits::Eight)
45//!     .stop_bits(some_serial::StopBits::One)
46//!     .parity(some_serial::Parity::None);
47//!
48//! uart.set_config(&config).unwrap();
49//! uart.open().unwrap();
50//! ```
51
52pub mod ns16550;
53pub mod pl011;
54
55use enum_dispatch::enum_dispatch;
56// 重新导出 rdif-serial 的所有类型
57pub use rdif_serial::*;
58
59#[enum_dispatch]
60pub enum Sender {
61    #[cfg(target_arch = "x86_64")]
62    Ns16550Sender(ns16550::Ns16550Sender<ns16550::Port>),
63    Ns16550MmioSender(ns16550::Ns16550Sender<ns16550::Mmio>),
64    Ns16550DwApbSender(ns16550::Ns16550Sender<ns16550::DwApb>),
65    Ns16550RockchipFiqSender(ns16550::rockchip_fiq::RockchipFiqSender),
66    Pl011Sender(pl011::Pl011Sender),
67}
68
69#[enum_dispatch(Sender)]
70trait RawSender {
71    fn write_byte(&mut self, byte: u8) -> bool;
72    fn write_bytes(&mut self, buffer: &[u8]) -> usize {
73        let mut written = 0;
74        for &byte in buffer.iter() {
75            if !self.write_byte(byte) {
76                break;
77            }
78            written += 1;
79        }
80        written
81    }
82}
83
84impl TSender for Sender {
85    fn write_byte(&mut self, byte: u8) -> bool {
86        RawSender::write_byte(self, byte)
87    }
88
89    fn write_bytes(&mut self, buffer: &[u8]) -> usize {
90        RawSender::write_bytes(self, buffer)
91    }
92}
93
94#[enum_dispatch]
95pub enum Reciever {
96    #[cfg(target_arch = "x86_64")]
97    Ns16550Reciever(ns16550::Ns16550Reciever<ns16550::Port>),
98    Ns16550MmioReciever(ns16550::Ns16550Reciever<ns16550::Mmio>),
99    Ns16550DwApbReciever(ns16550::Ns16550Reciever<ns16550::DwApb>),
100    Ns16550RockchipFiqReciever(ns16550::rockchip_fiq::RockchipFiqReceiver),
101    Pl011Reciever(pl011::Pl011Reciever),
102}
103
104impl TReciever for Reciever {
105    fn read_byte(&mut self) -> Option<Result<u8, TransferError>> {
106        RawReciever::read_byte(self)
107    }
108
109    fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
110        RawReciever::read_bytes(self, bytes)
111    }
112}
113
114#[enum_dispatch(Reciever)]
115trait RawReciever {
116    fn read_byte(&mut self) -> Option<Result<u8, TransferError>>;
117
118    fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
119        let mut read_count = 0;
120        for byte in bytes.iter_mut() {
121            match self.read_byte() {
122                Some(Ok(b)) => {
123                    *byte = b;
124                }
125                Some(Err(e)) => {
126                    return Err(TransBytesError {
127                        bytes_transferred: read_count,
128                        kind: e,
129                    });
130                }
131                None => break,
132            }
133
134            read_count += 1;
135        }
136        Ok(read_count)
137    }
138}