some_serial/
pl011.rs

1use core::ptr::NonNull;
2
3use crate::Register;
4use rdif_serial::{RegisterTransferError as TransferError, Serial, SerialRaw};
5use tock_registers::{interfaces::*, register_bitfields, register_structs, registers::*};
6
7use crate::{Config, ConfigError, DataBits, InterruptMask, LineStatus, Parity, StopBits};
8
9register_bitfields! [
10    u32,
11
12    /// Data Register
13    UARTDR [
14        DATA OFFSET(0) NUMBITS(8) [],
15        FE OFFSET(8) NUMBITS(1) [],
16        PE OFFSET(9) NUMBITS(1) [],
17        BE OFFSET(10) NUMBITS(1) [],
18        OE OFFSET(11) NUMBITS(1) []
19    ],
20
21    /// Receive Status Register / Error Clear Register
22    UARTRSR_ECR [
23        FE OFFSET(0) NUMBITS(1) [],
24        PE OFFSET(1) NUMBITS(1) [],
25        BE OFFSET(2) NUMBITS(1) [],
26        OE OFFSET(3) NUMBITS(1) []
27    ],
28
29    /// Flag Register
30    UARTFR [
31        CTS OFFSET(0) NUMBITS(1) [],
32        DSR OFFSET(1) NUMBITS(1) [],
33        DCD OFFSET(2) NUMBITS(1) [],
34        BUSY OFFSET(3) NUMBITS(1) [],
35        RXFE OFFSET(4) NUMBITS(1) [],
36        TXFF OFFSET(5) NUMBITS(1) [],
37        RXFF OFFSET(6) NUMBITS(1) [],
38        TXFE OFFSET(7) NUMBITS(1) [],
39        RI OFFSET(8) NUMBITS(1) []
40    ],
41
42    /// Integer Baud Rate Register
43    UARTIBRD [
44        BAUD_DIVINT OFFSET(0) NUMBITS(16) []
45    ],
46
47    /// Fractional Baud Rate Register
48    UARTFBRD [
49        BAUD_DIVFRAC OFFSET(0) NUMBITS(6) []
50    ],
51
52    /// Line Control Register
53    UARTLCR_H [
54        BRK OFFSET(0) NUMBITS(1) [],
55        PEN OFFSET(1) NUMBITS(1) [],
56        EPS OFFSET(2) NUMBITS(1) [],
57        STP2 OFFSET(3) NUMBITS(1) [],
58        FEN OFFSET(4) NUMBITS(1) [],
59        WLEN OFFSET(5) NUMBITS(2) [
60            FiveBit = 0,
61            SixBit = 1,
62            SevenBit = 2,
63            EightBit = 3
64        ],
65        SPS OFFSET(7) NUMBITS(1) []
66    ],
67
68    /// Control Register
69    UARTCR [
70        UARTEN OFFSET(0) NUMBITS(1) [],
71        SIREN OFFSET(1) NUMBITS(1) [],
72        SIRLP OFFSET(2) NUMBITS(1) [],
73        LBE OFFSET(7) NUMBITS(1) [],
74        TXE OFFSET(8) NUMBITS(1) [],
75        RXE OFFSET(9) NUMBITS(1) [],
76        DTR OFFSET(10) NUMBITS(1) [],
77        RTS OFFSET(11) NUMBITS(1) [],
78        OUT1 OFFSET(12) NUMBITS(1) [],
79        OUT2 OFFSET(13) NUMBITS(1) [],
80        RTSEN OFFSET(14) NUMBITS(1) [],
81        CTSEN OFFSET(15) NUMBITS(1) []
82    ],
83
84    /// Interrupt FIFO Level Select Register
85    UARTIFLS [
86        TXIFLSEL OFFSET(0) NUMBITS(3) [],
87        RXIFLSEL OFFSET(3) NUMBITS(3) []
88    ],
89
90    /// Interrupt Mask Set/Clear Register
91    UARTIS [
92        RIM OFFSET(0) NUMBITS(1) [],
93        CTSM OFFSET(1) NUMBITS(1) [],
94        DCDM OFFSET(2) NUMBITS(1) [],
95        DSRM OFFSET(3) NUMBITS(1) [],
96        RX OFFSET(4) NUMBITS(1) [],
97        TX OFFSET(5) NUMBITS(1) [],
98        RT OFFSET(6) NUMBITS(1) [],
99        FE OFFSET(7) NUMBITS(1) [],
100        PE OFFSET(8) NUMBITS(1) [],
101        BE OFFSET(9) NUMBITS(1) [],
102        OE OFFSET(10) NUMBITS(1) []
103    ],
104
105    /// DMA Control Register
106    UARTDMACR [
107        RXDMAE OFFSET(0) NUMBITS(1) [],
108        TXDMAE OFFSET(1) NUMBITS(1) [],
109        DMAONERR OFFSET(2) NUMBITS(1) []
110    ]
111];
112
113register_structs! {
114    pub Pl011Registers {
115        (0x000 => uartdr: ReadWrite<u32, UARTDR::Register>),        // 数据寄存器(收发数据/错误标志)
116        (0x004 => uartrsr_ecr: ReadWrite<u32, UARTRSR_ECR::Register>), // 接收状态/错误清除寄存器
117        (0x008 => _reserved1),                                      // 保留
118        (0x018 => uartfr: ReadOnly<u32, UARTFR::Register>),         // 标志寄存器(状态标志,如忙/空/满等)
119        (0x01c => _reserved2),                                      // 保留
120        (0x020 => uartilpr: ReadWrite<u32>),                        // 红外低功耗波特率寄存器(很少用)
121        (0x024 => uartibrd: ReadWrite<u32, UARTIBRD::Register>),    // 整数波特率分频寄存器
122        (0x028 => uartfbrd: ReadWrite<u32, UARTFBRD::Register>),    // 小数波特率分频寄存器
123        (0x02c => uartlcr_h: ReadWrite<u32, UARTLCR_H::Register>),  // 线路控制寄存器(数据位、停止位、校验等)
124        (0x030 => uartcr: ReadWrite<u32, UARTCR::Register>),        // 控制寄存器(UART使能、收发使能等)
125        (0x034 => uartifls: ReadWrite<u32, UARTIFLS::Register>),    // FIFO中断触发级别选择寄存器
126        (0x038 => uartimsc: ReadWrite<u32, UARTIS::Register>),      // 中断屏蔽设置/清除寄存器
127        (0x03c => uartris: ReadOnly<u32, UARTIS::Register>),        // 原始中断状态寄存器
128        (0x040 => uartmis: ReadOnly<u32, UARTIS::Register>),        // 屏蔽后的中断状态寄存器
129        (0x044 => uarticr: WriteOnly<u32, UARTIS::Register>),       // 中断清除寄存器
130        (0x048 => uartdmacr: ReadWrite<u32, UARTDMACR::Register>),  // DMA控制寄存器
131        (0x04c => _reserved3),                                      // 保留
132        (0x1000 => @END),
133    }
134}
135
136// SAFETY: PL011 寄存器访问是原子的,硬件保证了内存映射寄存器的线程安全
137unsafe impl Sync for Pl011Registers {}
138
139/// PL011 UART 驱动结构体
140#[derive(Clone)]
141pub struct Pl011 {
142    base: NonNull<Pl011Registers>,
143    clock_freq: u32,
144}
145
146unsafe impl Send for Pl011 {}
147unsafe impl Sync for Pl011 {}
148
149impl Pl011 {
150    /// 创建新的 PL011 实例(仅基地址,使用默认配置)
151    ///
152    /// # Arguments
153    /// * `base` - UART 寄存器基地址
154    pub fn new_raw_no_clock(base: NonNull<u8>) -> SerialRaw<Self> {
155        // 自动检测时钟频率或使用合理的默认值
156        let clock_freq = Self::detect_clock_frequency(base.as_ptr() as usize);
157        Self::new_raw(base, clock_freq)
158    }
159
160    /// 创建新的 PL011 实例(指定时钟频率)
161    ///
162    /// # Arguments
163    /// * `base` - UART 寄存器基地址
164    /// * `clock_freq` - UART 时钟频率 (Hz)
165    pub fn new_raw(base: NonNull<u8>, clock_freq: u32) -> SerialRaw<Self> {
166        SerialRaw::new(Self {
167            base: base.cast(),
168            clock_freq,
169        })
170    }
171
172    pub fn new(base: NonNull<u8>, clock_freq: u32) -> Serial<Self> {
173        Serial::new(Self {
174            base: base.cast(),
175            clock_freq,
176        })
177    }
178
179    fn registers(&self) -> &Pl011Registers {
180        unsafe { self.base.as_ref() }
181    }
182
183    /// 自动检测或确定合理的时钟频率
184    fn detect_clock_frequency(base: usize) -> u32 {
185        // 尝试读取当前波特率设置来反向推算时钟频率
186        let registers = unsafe { &*(base as *const Pl011Registers) };
187
188        use tock_registers::interfaces::Readable;
189        let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
190
191        // 如果有设置值,假设波特率为 115200 来估算时钟频率
192        if ibrd > 0 && ibrd <= 0xFFFF {
193            // 假设波特率为 115200,计算时钟频率
194            // FUARTCLK = 16 * BAUDDIV * Baud rate
195            let estimated_clock = 16 * ibrd * 115200;
196
197            // 合理的时钟频率范围:1MHz - 100MHz
198            if (1_000_000..=100_000_000).contains(&estimated_clock) {
199                return estimated_clock;
200            }
201        }
202
203        // 默认使用 24MHz(最常见)
204        24_000_000
205    }
206
207    // 内部私有方法,用于配置
208    fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
209        // PL011 波特率计算公式:
210        // BAUDDIV = (FUARTCLK / (16 * Baud rate))
211        // IBRD = integer(BAUDDIV)
212        // FBRD = integer((BAUDDIV - IBRD) * 64 + 0.5)
213
214        let bauddiv = self.clock_freq / (16 * baudrate);
215        let remainder = self.clock_freq % (16 * baudrate);
216        let fbrd = (remainder * 64 + (16 * baudrate / 2)) / (16 * baudrate);
217
218        if bauddiv == 0 || bauddiv > 0xFFFF {
219            return Err(ConfigError::InvalidBaudrate);
220        }
221
222        self.registers()
223            .uartibrd
224            .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
225        self.registers()
226            .uartfbrd
227            .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
228
229        Ok(())
230    }
231
232    fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
233        let wlen = match bits {
234            DataBits::Five => UARTLCR_H::WLEN::FiveBit,
235            DataBits::Six => UARTLCR_H::WLEN::SixBit,
236            DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
237            DataBits::Eight => UARTLCR_H::WLEN::EightBit,
238        };
239
240        self.registers().uartlcr_h.modify(wlen);
241        Ok(())
242    }
243
244    fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
245        match bits {
246            StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
247            StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
248        }
249
250        Ok(())
251    }
252
253    fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
254        match parity {
255            Parity::None => {
256                // PEN = 0, 无奇偶校验
257                self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
258            }
259            Parity::Odd => {
260                // PEN = 1, EPS = 0 (奇校验), SPS = 0
261                self.registers()
262                    .uartlcr_h
263                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
264            }
265            Parity::Even => {
266                // PEN = 1, EPS = 1 (偶校验), SPS = 0
267                self.registers()
268                    .uartlcr_h
269                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
270            }
271            Parity::Mark => {
272                // PEN = 1, SPS = 1, EPS = 0 (奇校验)
273                self.registers()
274                    .uartlcr_h
275                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
276            }
277            Parity::Space => {
278                // PEN = 1, EPS = 1 (偶校验), SPS = 1
279                self.registers()
280                    .uartlcr_h
281                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
282            }
283        }
284
285        Ok(())
286    }
287
288    /// 初始化 PL011 UART
289    fn init(&self) {
290        // 禁用 UART
291        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
292
293        // 等待当前传输完成
294        while self.registers().uartfr.is_set(UARTFR::BUSY) {
295            core::hint::spin_loop();
296        }
297
298        // 清除发送 FIFO
299        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
300
301        // 启用 FIFO
302        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
303
304        // 调试信息:输出 FIFO 配置
305        #[cfg(debug_assertions)]
306        {
307            let ifls = self.registers().uartifls.get();
308            let lcr_h = self.registers().uartlcr_h.get();
309            log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
310            log::debug!("  FIFO enabled: {}", lcr_h & (1 << 4) != 0);
311            log::debug!("  RX trigger level: 1/8");
312            log::debug!("  TX trigger level: 1/2");
313        }
314        self.registers().uartimsc.set(0); // 禁用所有中断
315                                          // 启用 UART
316        self.registers()
317            .uartcr
318            .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
319    }
320}
321
322impl Register for Pl011 {
323    fn write_byte(&mut self, byte: u8) {
324        self.registers().uartdr.write(UARTDR::DATA.val(byte as u32));
325    }
326
327    fn read_byte(&self) -> Result<u8, TransferError> {
328        let dr = self.registers().uartdr.extract();
329        let data = dr.read(UARTDR::DATA) as u8;
330
331        if dr.is_set(UARTDR::FE) {
332            return Err(TransferError::Framing);
333        }
334
335        if dr.is_set(UARTDR::PE) {
336            return Err(TransferError::Parity);
337        }
338
339        if dr.is_set(UARTDR::OE) {
340            return Err(TransferError::Overrun(data));
341        }
342
343        if dr.is_set(UARTDR::BE) {
344            return Err(TransferError::Break);
345        }
346
347        Ok(data)
348    }
349
350    fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
351        use tock_registers::interfaces::Readable;
352
353        // 根据ARM文档的建议配置流程:
354        // 1. 禁用UART
355        let original_enable = self.registers().uartcr.is_set(UARTCR::UARTEN); // 保存原始使能状态
356        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR); // 禁用UART
357
358        // 2. 等待当前字符传输完成
359        while self.registers().uartfr.is_set(UARTFR::BUSY) {
360            core::hint::spin_loop();
361        }
362
363        // 3. 刷新发送FIFO(通过设置FEN=0)
364        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
365
366        // 4. 配置各项参数
367        if let Some(baudrate) = config.baudrate {
368            self.set_baudrate_internal(baudrate)?;
369        }
370        if let Some(data_bits) = config.data_bits {
371            self.set_data_bits_internal(data_bits)?;
372        }
373        if let Some(stop_bits) = config.stop_bits {
374            self.set_stop_bits_internal(stop_bits)?;
375        }
376        if let Some(parity) = config.parity {
377            self.set_parity_internal(parity)?;
378        }
379
380        // 5. 重新启用FIFO
381        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
382
383        // 6. 恢复UART使能状态
384        if original_enable {
385            self.registers().uartcr.modify(UARTCR::UARTEN::SET); // 重新启用UART
386        }
387
388        Ok(())
389    }
390
391    fn baudrate(&self) -> u32 {
392        let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
393        let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
394
395        // 反向计算波特率
396        // Baud rate = FUARTCLK / (16 * (IBRD + FBRD/64))
397        let divisor = ibrd * 64 + fbrd;
398        if divisor == 0 {
399            return 0;
400        }
401
402        self.clock_freq * 64 / (16 * divisor)
403    }
404
405    fn data_bits(&self) -> DataBits {
406        let wlen = self.registers().uartlcr_h.read(UARTLCR_H::WLEN);
407
408        match wlen {
409            0 => DataBits::Five,
410            1 => DataBits::Six,
411            2 => DataBits::Seven,
412            3 => DataBits::Eight,
413            _ => DataBits::Eight, // 默认值
414        }
415    }
416
417    fn stop_bits(&self) -> StopBits {
418        if self.registers().uartlcr_h.is_set(UARTLCR_H::STP2) {
419            StopBits::Two
420        } else {
421            StopBits::One
422        }
423    }
424
425    fn parity(&self) -> Parity {
426        if !self.registers().uartlcr_h.is_set(UARTLCR_H::PEN) {
427            Parity::None
428        } else if self.registers().uartlcr_h.is_set(UARTLCR_H::SPS) {
429            // Stick parity
430            if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
431                Parity::Space
432            } else {
433                Parity::Mark
434            }
435        } else {
436            // Normal parity
437            if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
438                Parity::Even
439            } else {
440                Parity::Odd
441            }
442        }
443    }
444
445    fn open(&mut self) {
446        self.init()
447    }
448
449    fn close(&mut self) {
450        // 禁用 UART
451        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
452    }
453
454    fn clean_interrupt_status(&mut self) -> InterruptMask {
455        let mis = self.registers().uartmis.extract();
456        let mut mask = InterruptMask::empty();
457
458        if mis.is_set(UARTIS::RX) {
459            mask |= InterruptMask::RX_AVAILABLE;
460        }
461        if mis.is_set(UARTIS::TX) {
462            mask |= InterruptMask::TX_EMPTY;
463        }
464
465        self.registers().uarticr.set(mis.get());
466
467        mask
468    }
469
470    fn line_status(&self) -> LineStatus {
471        use tock_registers::interfaces::Readable;
472        let mut status = LineStatus::empty();
473
474        let fr = self.registers().uartfr.extract();
475
476        if !fr.is_set(UARTFR::RXFE) {
477            status |= LineStatus::DATA_READY;
478        }
479
480        if !fr.is_set(UARTFR::TXFF) {
481            status |= LineStatus::TX_HOLDING_EMPTY;
482        }
483
484        status
485    }
486
487    fn read_reg(&self, offset: usize) -> u32 {
488        let addr = unsafe { self.base.cast::<u8>().add(offset) };
489        unsafe { addr.cast().read_volatile() }
490    }
491
492    fn write_reg(&mut self, offset: usize, value: u32) {
493        let addr = unsafe { self.base.cast::<u8>().add(offset) };
494        unsafe { addr.cast().write_volatile(value) };
495    }
496
497    fn get_base(&self) -> usize {
498        self.base.as_ptr() as usize
499    }
500
501    fn set_base(&mut self, base: NonNull<u8>) {
502        self.base = base.cast();
503    }
504
505    fn clock_freq(&self) -> u32 {
506        self.clock_freq
507    }
508
509    fn enable_loopback(&mut self) {
510        self.registers().uartcr.modify(UARTCR::LBE::SET);
511    }
512
513    fn disable_loopback(&mut self) {
514        self.registers().uartcr.modify(UARTCR::LBE::CLEAR);
515    }
516
517    fn is_loopback_enabled(&self) -> bool {
518        self.registers().uartcr.is_set(UARTCR::LBE)
519    }
520
521    fn set_irq_mask(&mut self, mask: InterruptMask) {
522        let mut imsc = 0;
523        if mask.contains(InterruptMask::RX_AVAILABLE) {
524            imsc += UARTIS::RX::SET.value;
525        }
526        if mask.contains(InterruptMask::TX_EMPTY) {
527            imsc += UARTIS::TX::SET.value;
528        }
529
530        self.registers().uartimsc.set(imsc);
531    }
532
533    fn get_irq_mask(&self) -> InterruptMask {
534        let imsc = self.registers().uartimsc.extract();
535        let mut mask = InterruptMask::empty();
536
537        if imsc.is_set(UARTIS::RX) {
538            mask |= InterruptMask::RX_AVAILABLE;
539        }
540        if imsc.is_set(UARTIS::TX) {
541            mask |= InterruptMask::TX_EMPTY;
542        }
543
544        mask
545    }
546}
547
548// 额外的便利方法,用于 FIFO 和流控制
549impl Pl011 {
550    /// 启用或禁用 FIFO
551    pub fn enable_fifo(&self, enable: bool) {
552        if enable {
553            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
554        } else {
555            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
556        }
557    }
558
559    /// 设置 FIFO 触发级别
560    pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
561        // PL011 FIFO 触发级别:
562        // 0b000: 1/8 full
563        // 0b001: 1/4 full
564        // 0b010: 1/2 full
565        // 0b011: 3/4 full
566        // 0b100: 7/8 full
567
568        let rx_iflsel = match rx_level {
569            0..=2 => 0b000,  // 1/8
570            3..=4 => 0b001,  // 1/4
571            5..=8 => 0b010,  // 1/2
572            9..=12 => 0b011, // 3/4
573            _ => 0b100,      // 7/8
574        };
575
576        let tx_iflsel = match tx_level {
577            0..=2 => 0b000,  // 1/8
578            3..=4 => 0b001,  // 1/4
579            5..=8 => 0b010,  // 1/2
580            9..=12 => 0b011, // 3/4
581            _ => 0b100,      // 7/8
582        };
583
584        self.registers()
585            .uartifls
586            .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
587    }
588}
589
590// ModemStatus 现在在 lib.rs 中定义,这里只是导出