Skip to main content

some_serial/
pl011.rs

1use core::ptr::NonNull;
2
3use rdif_serial::{
4    Config, ConfigError, DataBits, IrqRxSink, Parity, RxErrorFlags, RxFlag, RxSample,
5    SerialEventSet, SerialIrqEvent, SplitUart, StopBits, UartInfo, UartIrq, UartParts, UartPort,
6};
7use tock_registers::{
8    LocalRegisterCopy, interfaces::*, register_bitfields, register_structs, registers::*,
9};
10
11use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
12
13register_bitfields! [
14    u32,
15
16    /// Data Register
17    UARTDR [
18        DATA OFFSET(0) NUMBITS(8) [],
19        FE OFFSET(8) NUMBITS(1) [],
20        PE OFFSET(9) NUMBITS(1) [],
21        BE OFFSET(10) NUMBITS(1) [],
22        OE OFFSET(11) NUMBITS(1) []
23    ],
24
25    /// Receive Status Register / Error Clear Register
26    UARTRSR_ECR [
27        FE OFFSET(0) NUMBITS(1) [],
28        PE OFFSET(1) NUMBITS(1) [],
29        BE OFFSET(2) NUMBITS(1) [],
30        OE OFFSET(3) NUMBITS(1) []
31    ],
32
33    /// Flag Register
34    UARTFR [
35        CTS OFFSET(0) NUMBITS(1) [],
36        DSR OFFSET(1) NUMBITS(1) [],
37        DCD OFFSET(2) NUMBITS(1) [],
38        BUSY OFFSET(3) NUMBITS(1) [],
39        RXFE OFFSET(4) NUMBITS(1) [],
40        TXFF OFFSET(5) NUMBITS(1) [],
41        RXFF OFFSET(6) NUMBITS(1) [],
42        TXFE OFFSET(7) NUMBITS(1) [],
43        RI OFFSET(8) NUMBITS(1) []
44    ],
45
46    /// Integer Baud Rate Register
47    UARTIBRD [
48        BAUD_DIVINT OFFSET(0) NUMBITS(16) []
49    ],
50
51    /// Fractional Baud Rate Register
52    UARTFBRD [
53        BAUD_DIVFRAC OFFSET(0) NUMBITS(6) []
54    ],
55
56    /// Line Control Register
57    UARTLCR_H [
58        BRK OFFSET(0) NUMBITS(1) [],
59        PEN OFFSET(1) NUMBITS(1) [],
60        EPS OFFSET(2) NUMBITS(1) [],
61        STP2 OFFSET(3) NUMBITS(1) [],
62        FEN OFFSET(4) NUMBITS(1) [],
63        WLEN OFFSET(5) NUMBITS(2) [
64            FiveBit = 0,
65            SixBit = 1,
66            SevenBit = 2,
67            EightBit = 3
68        ],
69        SPS OFFSET(7) NUMBITS(1) []
70    ],
71
72    /// Control Register
73    UARTCR [
74        UARTEN OFFSET(0) NUMBITS(1) [],
75        SIREN OFFSET(1) NUMBITS(1) [],
76        SIRLP OFFSET(2) NUMBITS(1) [],
77        LBE OFFSET(7) NUMBITS(1) [],
78        TXE OFFSET(8) NUMBITS(1) [],
79        RXE OFFSET(9) NUMBITS(1) [],
80        DTR OFFSET(10) NUMBITS(1) [],
81        RTS OFFSET(11) NUMBITS(1) [],
82        OUT1 OFFSET(12) NUMBITS(1) [],
83        OUT2 OFFSET(13) NUMBITS(1) [],
84        RTSEN OFFSET(14) NUMBITS(1) [],
85        CTSEN OFFSET(15) NUMBITS(1) []
86    ],
87
88    /// Interrupt FIFO Level Select Register
89    UARTIFLS [
90        TXIFLSEL OFFSET(0) NUMBITS(3) [],
91        RXIFLSEL OFFSET(3) NUMBITS(3) []
92    ],
93
94    /// Interrupt Mask Set/Clear Register
95    UARTIS [
96        RIM OFFSET(0) NUMBITS(1) [],
97        CTSM OFFSET(1) NUMBITS(1) [],
98        DCDM OFFSET(2) NUMBITS(1) [],
99        DSRM OFFSET(3) NUMBITS(1) [],
100        RX OFFSET(4) NUMBITS(1) [],
101        TX OFFSET(5) NUMBITS(1) [],
102        RT OFFSET(6) NUMBITS(1) [],
103        FE OFFSET(7) NUMBITS(1) [],
104        PE OFFSET(8) NUMBITS(1) [],
105        BE OFFSET(9) NUMBITS(1) [],
106        OE OFFSET(10) NUMBITS(1) []
107    ],
108
109    /// DMA Control Register
110    UARTDMACR [
111        RXDMAE OFFSET(0) NUMBITS(1) [],
112        TXDMAE OFFSET(1) NUMBITS(1) [],
113        DMAONERR OFFSET(2) NUMBITS(1) []
114    ]
115];
116
117register_structs! {
118    pub Pl011Registers {
119        (0x000 => uartdr: ReadWrite<u32, UARTDR::Register>),        // 数据寄存器(收发数据/错误标志)
120        (0x004 => uartrsr_ecr: ReadWrite<u32, UARTRSR_ECR::Register>), // 接收状态/错误清除寄存器
121        (0x008 => _reserved1),                                      // 保留
122        (0x018 => uartfr: ReadOnly<u32, UARTFR::Register>),         // 标志寄存器(状态标志,如忙/空/满等)
123        (0x01c => _reserved2),                                      // 保留
124        (0x020 => uartilpr: ReadWrite<u32>),                        // 红外低功耗波特率寄存器(很少用)
125        (0x024 => uartibrd: ReadWrite<u32, UARTIBRD::Register>),    // 整数波特率分频寄存器
126        (0x028 => uartfbrd: ReadWrite<u32, UARTFBRD::Register>),    // 小数波特率分频寄存器
127        (0x02c => uartlcr_h: ReadWrite<u32, UARTLCR_H::Register>),  // 线路控制寄存器(数据位、停止位、校验等)
128        (0x030 => uartcr: ReadWrite<u32, UARTCR::Register>),        // 控制寄存器(UART使能、收发使能等)
129        (0x034 => uartifls: ReadWrite<u32, UARTIFLS::Register>),    // FIFO中断触发级别选择寄存器
130        (0x038 => uartimsc: ReadWrite<u32, UARTIS::Register>),      // 中断屏蔽设置/清除寄存器
131        (0x03c => uartris: ReadOnly<u32, UARTIS::Register>),        // 原始中断状态寄存器
132        (0x040 => uartmis: ReadOnly<u32, UARTIS::Register>),        // 屏蔽后的中断状态寄存器
133        (0x044 => uarticr: WriteOnly<u32, UARTIS::Register>),       // 中断清除寄存器
134        (0x048 => uartdmacr: ReadWrite<u32, UARTDMACR::Register>),  // DMA控制寄存器
135        (0x04c => _reserved3),                                      // 保留
136        (0x1000 => @END),
137    }
138}
139
140// SAFETY: PL011 寄存器访问是原子的,硬件保证了内存映射寄存器的线程安全
141unsafe impl Sync for Pl011Registers {}
142
143/// PL011 UART 驱动结构体
144pub struct Pl011 {
145    base: Reg,
146    clock_freq: u32,
147    saved_rx_status: Pl011RxStatus,
148}
149
150impl Pl011 {
151    /// 创建新的 PL011 实例(仅基地址,使用默认配置)
152    ///
153    /// # Arguments
154    /// * `base` - UART 寄存器基地址
155    pub fn new_no_clock(base: NonNull<u8>) -> Self {
156        // 自动检测时钟频率或使用合理的默认值
157        let clock_freq = Self::detect_clock_frequency(base.as_ptr() as usize);
158        Self::new(base, clock_freq)
159    }
160
161    pub fn new(base: NonNull<u8>, clock_freq: u32) -> Self {
162        let base = Reg(base.cast());
163
164        Self {
165            base,
166            clock_freq,
167            saved_rx_status: Pl011RxStatus::empty(),
168        }
169    }
170
171    fn registers(&self) -> &Pl011Registers {
172        unsafe { &*self.base.0.as_ptr() }
173    }
174
175    fn current_baudrate(&self) -> u32 {
176        let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
177        let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
178        let divisor = ibrd * 64 + fbrd;
179        if divisor == 0 {
180            0
181        } else {
182            self.clock_freq * 64 / (16 * divisor)
183        }
184    }
185
186    /// 自动检测或确定合理的时钟频率
187    fn detect_clock_frequency(base: usize) -> u32 {
188        // 尝试读取当前波特率设置来反向推算时钟频率
189        let registers = unsafe { &*(base as *const Pl011Registers) };
190
191        use tock_registers::interfaces::Readable;
192        let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
193
194        // 如果有设置值,假设波特率为 115200 来估算时钟频率
195        if ibrd > 0 && ibrd <= 0xFFFF {
196            // 假设波特率为 115200,计算时钟频率
197            // FUARTCLK = 16 * BAUDDIV * Baud rate
198            let estimated_clock = 16 * ibrd * 115200;
199
200            // 合理的时钟频率范围:1MHz - 100MHz
201            if (1_000_000..=100_000_000).contains(&estimated_clock) {
202                return estimated_clock;
203            }
204        }
205
206        // 默认使用 24MHz(最常见)
207        24_000_000
208    }
209
210    // 内部私有方法,用于配置
211    fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
212        // PL011 波特率计算公式:
213        // BAUDDIV = (FUARTCLK / (16 * Baud rate))
214        // IBRD = integer(BAUDDIV)
215        // FBRD = integer((BAUDDIV - IBRD) * 64 + 0.5)
216
217        let bauddiv = self.clock_freq / (16 * baudrate);
218        let remainder = self.clock_freq % (16 * baudrate);
219        let fbrd = (remainder * 64 + (16 * baudrate / 2)) / (16 * baudrate);
220
221        if bauddiv == 0 || bauddiv > 0xFFFF {
222            return Err(ConfigError::InvalidBaudrate);
223        }
224
225        self.registers()
226            .uartibrd
227            .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
228        self.registers()
229            .uartfbrd
230            .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
231
232        Ok(())
233    }
234
235    fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
236        let wlen = match bits {
237            DataBits::Five => UARTLCR_H::WLEN::FiveBit,
238            DataBits::Six => UARTLCR_H::WLEN::SixBit,
239            DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
240            DataBits::Eight => UARTLCR_H::WLEN::EightBit,
241        };
242
243        self.registers().uartlcr_h.modify(wlen);
244        Ok(())
245    }
246
247    fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
248        match bits {
249            StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
250            StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
251        }
252
253        Ok(())
254    }
255
256    fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
257        match parity {
258            Parity::None => {
259                // PEN = 0, 无奇偶校验
260                self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
261            }
262            Parity::Odd => {
263                // PEN = 1, EPS = 0 (奇校验), SPS = 0
264                self.registers()
265                    .uartlcr_h
266                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
267            }
268            Parity::Even => {
269                // PEN = 1, EPS = 1 (偶校验), SPS = 0
270                self.registers()
271                    .uartlcr_h
272                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
273            }
274            Parity::Mark => {
275                // PEN = 1, SPS = 1, EPS = 0 (奇校验)
276                self.registers()
277                    .uartlcr_h
278                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
279            }
280            Parity::Space => {
281                // PEN = 1, EPS = 1 (偶校验), SPS = 1
282                self.registers()
283                    .uartlcr_h
284                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
285            }
286        }
287
288        Ok(())
289    }
290
291    /// 初始化 PL011 UART
292    pub fn open(&mut self) {
293        // 禁用 UART
294        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
295
296        // 等待当前传输完成
297        while self.registers().uartfr.is_set(UARTFR::BUSY) {
298            core::hint::spin_loop();
299        }
300
301        // 清除发送 FIFO
302        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
303
304        // 启用 FIFO
305        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
306
307        // 调试信息:输出 FIFO 配置
308        #[cfg(debug_assertions)]
309        {
310            let ifls = self.registers().uartifls.get();
311            let lcr_h = self.registers().uartlcr_h.get();
312            log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
313            log::debug!("  FIFO enabled: {}", lcr_h & (1 << 4) != 0);
314            log::debug!("  RX trigger level: 1/8");
315            log::debug!("  TX trigger level: 1/2");
316        }
317        self.registers().uartimsc.set(0); // 禁用所有中断
318        // 启用 UART
319        self.registers()
320            .uartcr
321            .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
322    }
323
324    pub fn set_irq_mask(&mut self, events: SerialEventSet) {
325        self.registers().uartimsc.set(imsc_for_events(events));
326    }
327
328    pub fn get_irq_mask(&self) -> SerialEventSet {
329        let imsc = self.registers().uartimsc.extract();
330        let mut events = SerialEventSet::empty();
331
332        if imsc.is_set(UARTIS::RX)
333            || imsc.is_set(UARTIS::RT)
334            || imsc.is_set(UARTIS::FE)
335            || imsc.is_set(UARTIS::PE)
336            || imsc.is_set(UARTIS::BE)
337            || imsc.is_set(UARTIS::OE)
338        {
339            events |= SerialEventSet::RX;
340        }
341        if imsc.is_set(UARTIS::TX) {
342            events |= SerialEventSet::TX_SPACE;
343        }
344
345        events
346    }
347
348    pub fn pending(&mut self, direction: SerialDirection) -> bool {
349        match direction {
350            SerialDirection::Input => !self.registers().uartfr.is_set(UARTFR::RXFE),
351            SerialDirection::Output => !self.registers().uartfr.is_set(UARTFR::TXFF),
352        }
353    }
354
355    pub fn poll_status(&mut self) -> SerialEvent {
356        let mut event = SerialEvent::empty();
357        let fr = self.registers().uartfr.extract();
358        if !fr.is_set(UARTFR::RXFE) {
359            event |= SerialEvent::RX_READY;
360        }
361        if !fr.is_set(UARTFR::TXFF) {
362            event |= SerialEvent::TX_READY;
363        }
364
365        let status =
366            self.saved_rx_status | Pl011RxStatus::from_rsr(self.registers().uartrsr_ecr.extract());
367        if status.intersects(Pl011RxStatus::FRAMING | Pl011RxStatus::PARITY | Pl011RxStatus::BREAK)
368        {
369            event |= SerialEvent::RX_ERROR;
370        }
371        if status.contains(Pl011RxStatus::OVERRUN) {
372            event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
373        }
374
375        event
376    }
377
378    pub fn try_write(&mut self, bytes: &[u8]) -> usize {
379        let mut written = 0;
380        for &byte in bytes {
381            let status = self.poll_status();
382            if !status.tx_ready() {
383                break;
384            }
385            self.write_byte(byte);
386            written += 1;
387        }
388        written
389    }
390
391    pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
392        let mut count = 0;
393        for byte in bytes.iter_mut() {
394            let status = self.poll_status();
395            if !status.rx_ready() && !status.rx_error() {
396                break;
397            }
398            match self.read_byte(status) {
399                Some(Ok(b)) => {
400                    *byte = b;
401                }
402                Some(Err(TransferError::Overrun(b))) => {
403                    *byte = b;
404                    count += 1;
405                    return Err(TransBytesError {
406                        bytes_transferred: count,
407                        kind: TransferError::Overrun(b),
408                    });
409                }
410                Some(Err(e)) => {
411                    return Err(TransBytesError {
412                        bytes_transferred: count,
413                        kind: e,
414                    });
415                }
416                None => break,
417            }
418            count += 1;
419        }
420        Ok(count)
421    }
422
423    pub fn write_byte(&mut self, byte: u8) {
424        self.registers().uartdr.set(byte as _);
425    }
426
427    pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
428        if !status.rx_ready() && !status.rx_error() {
429            return None;
430        }
431
432        let sample = self.read_rx()?;
433        if sample.overrun {
434            return Some(Err(TransferError::Overrun(sample.byte.unwrap_or(0))));
435        }
436        match sample.flag {
437            RxFlag::Normal => sample.byte.map(Ok),
438            RxFlag::Break => Some(Err(TransferError::Break)),
439            RxFlag::Parity => Some(Err(TransferError::Parity)),
440            RxFlag::Framing => Some(Err(TransferError::Framing)),
441        }
442    }
443
444    pub fn read_rx(&mut self) -> Option<RxSample> {
445        let base = self.base;
446        // SAFETY: `base` is the mapped PL011 register block owned by this
447        // endpoint and remains valid for the endpoint lifetime.
448        let registers = unsafe { &*base.0.as_ptr() };
449        read_rx_sample(registers, &mut self.saved_rx_status)
450    }
451}
452
453fn read_rx_sample(
454    registers: &Pl011Registers,
455    saved_status: &mut Pl011RxStatus,
456) -> Option<RxSample> {
457    if registers.uartfr.is_set(UARTFR::RXFE) {
458        *saved_status |= Pl011RxStatus::from_rsr(registers.uartrsr_ecr.extract());
459        return saved_status.take_status_sample();
460    }
461
462    let dr = registers.uartdr.extract();
463    let data = dr.read(UARTDR::DATA) as u8;
464    let status = Pl011RxStatus::from_data(dr);
465    if !status.is_empty() {
466        saved_status.remove(status);
467    }
468
469    Some(RxSample {
470        byte: Some(data),
471        flag: status.flag(),
472        overrun: status.contains(Pl011RxStatus::OVERRUN),
473    })
474}
475
476fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
477    let mut errors = match sample.flag {
478        RxFlag::Normal => RxErrorFlags::empty(),
479        RxFlag::Break => RxErrorFlags::BREAK,
480        RxFlag::Parity => RxErrorFlags::PARITY,
481        RxFlag::Framing => RxErrorFlags::FRAMING,
482    };
483    if sample.overrun {
484        errors |= RxErrorFlags::OVERRUN;
485    }
486    errors
487}
488
489bitflags::bitflags! {
490    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
491    struct Pl011RxStatus: u32 {
492        const FRAMING = 1 << 0;
493        const PARITY  = 1 << 1;
494        const BREAK   = 1 << 2;
495        const OVERRUN = 1 << 3;
496    }
497}
498
499impl Pl011RxStatus {
500    fn to_irq_errors(self) -> RxErrorFlags {
501        let mut errors = RxErrorFlags::empty();
502        if self.contains(Self::BREAK) {
503            errors |= RxErrorFlags::BREAK;
504        }
505        if self.contains(Self::PARITY) {
506            errors |= RxErrorFlags::PARITY;
507        }
508        if self.contains(Self::FRAMING) {
509            errors |= RxErrorFlags::FRAMING;
510        }
511        if self.contains(Self::OVERRUN) {
512            errors |= RxErrorFlags::OVERRUN;
513        }
514        errors
515    }
516
517    fn from_data(dr: LocalRegisterCopy<u32, UARTDR::Register>) -> Self {
518        let mut status = Self::empty();
519        if dr.is_set(UARTDR::FE) {
520            status |= Self::FRAMING;
521        }
522        if dr.is_set(UARTDR::PE) {
523            status |= Self::PARITY;
524        }
525        if dr.is_set(UARTDR::BE) {
526            status |= Self::BREAK;
527        }
528        if dr.is_set(UARTDR::OE) {
529            status |= Self::OVERRUN;
530        }
531        status
532    }
533
534    fn from_irq_status(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> Self {
535        let mut status = Self::empty();
536        if mis.is_set(UARTIS::FE) {
537            status |= Self::FRAMING;
538        }
539        if mis.is_set(UARTIS::PE) {
540            status |= Self::PARITY;
541        }
542        if mis.is_set(UARTIS::BE) {
543            status |= Self::BREAK;
544        }
545        if mis.is_set(UARTIS::OE) {
546            status |= Self::OVERRUN;
547        }
548        status
549    }
550
551    fn from_rsr(rsr: LocalRegisterCopy<u32, UARTRSR_ECR::Register>) -> Self {
552        let mut status = Self::empty();
553        if rsr.is_set(UARTRSR_ECR::FE) {
554            status |= Self::FRAMING;
555        }
556        if rsr.is_set(UARTRSR_ECR::PE) {
557            status |= Self::PARITY;
558        }
559        if rsr.is_set(UARTRSR_ECR::BE) {
560            status |= Self::BREAK;
561        }
562        if rsr.is_set(UARTRSR_ECR::OE) {
563            status |= Self::OVERRUN;
564        }
565        status
566    }
567
568    fn flag(self) -> RxFlag {
569        if self.contains(Self::BREAK) {
570            RxFlag::Break
571        } else if self.contains(Self::PARITY) {
572            RxFlag::Parity
573        } else if self.contains(Self::FRAMING) {
574            RxFlag::Framing
575        } else {
576            RxFlag::Normal
577        }
578    }
579
580    fn take_status_sample(&mut self) -> Option<RxSample> {
581        if self.is_empty() {
582            return None;
583        }
584
585        let status = *self;
586        *self = Self::empty();
587        Some(RxSample {
588            byte: None,
589            flag: status.flag(),
590            overrun: status.contains(Self::OVERRUN),
591        })
592    }
593}
594
595#[derive(Clone, Copy, PartialEq, Eq)]
596struct Reg(NonNull<Pl011Registers>);
597
598unsafe impl Send for Reg {}
599unsafe impl Sync for Reg {}
600
601/// IRQ-only endpoint for a PL011 UART.
602pub struct Pl011Irq {
603    base: Reg,
604    saved_rx_status: Pl011RxStatus,
605}
606
607impl Pl011Irq {
608    fn registers(&self) -> &Pl011Registers {
609        // SAFETY: `base` points at the mapped PL011 register block. The IRQ
610        // endpoint intentionally exposes no FIFO data methods.
611        unsafe { &*self.base.0.as_ptr() }
612    }
613}
614
615impl UartIrq for Pl011Irq {
616    fn handle(&mut self, rx: &mut dyn IrqRxSink) -> Option<SerialIrqEvent> {
617        const RX_SAMPLE_BUDGET: usize = 256;
618
619        let mis = self.registers().uartmis.extract();
620        let active = mis.get();
621        if active == 0 {
622            return None;
623        }
624
625        let mut events = events_from_mis(mis);
626        if active & !0x7ff != 0 {
627            events |= SerialEventSet::FAULT;
628        }
629        let mut rx_errors = rx_errors_from_mis(mis);
630        if events.intersects(SerialEventSet::RX) {
631            let base = self.base;
632            // SAFETY: `base` is the mapped PL011 register block shared with
633            // the task endpoint under the runtime's same-CPU exclusion rule.
634            let registers = unsafe { &*base.0.as_ptr() };
635            for _ in 0..RX_SAMPLE_BUDGET {
636                let Some(sample) = read_rx_sample(registers, &mut self.saved_rx_status) else {
637                    break;
638                };
639                rx_errors |= rx_errors_from_sample(sample);
640                rx.push(sample);
641            }
642        }
643
644        let rearm = events & SerialEventSet::TX_SPACE;
645        if events.contains(SerialEventSet::FAULT) {
646            self.registers().uartimsc.set(0);
647        } else if !rearm.is_empty() {
648            let enabled = self.registers().uartimsc.get();
649            self.registers()
650                .uartimsc
651                .set(enabled & !imsc_for_events(rearm));
652        }
653        self.registers().uarticr.set(active);
654
655        Some(SerialIrqEvent {
656            events,
657            rx_errors,
658            rearm,
659        })
660    }
661}
662
663impl UartPort for Pl011 {
664    fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
665        self.open();
666        self.set_config(config)?;
667        self.mask_all();
668        Ok(())
669    }
670
671    fn shutdown(&mut self) {
672        self.registers().uartimsc.set(0);
673        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
674    }
675
676    fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
677        use tock_registers::interfaces::Readable;
678
679        // 根据ARM文档的建议配置流程:
680        // 1. 禁用UART
681        let original_cr = self.registers().uartcr.extract(); // 保存原始使能状态
682        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR); // 禁用UART
683
684        // 2. 等待当前字符传输完成
685        while self.registers().uartfr.is_set(UARTFR::BUSY) {
686            core::hint::spin_loop();
687        }
688
689        // 3. 刷新发送FIFO(通过设置FEN=0)
690        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
691
692        // 4. 配置各项参数
693        if let Some(baudrate) = config.baudrate {
694            self.set_baudrate_internal(baudrate)?;
695        }
696        if let Some(data_bits) = config.data_bits {
697            self.set_data_bits_internal(data_bits)?;
698        }
699        if let Some(stop_bits) = config.stop_bits {
700            self.set_stop_bits_internal(stop_bits)?;
701        }
702        if let Some(parity) = config.parity {
703            self.set_parity_internal(parity)?;
704        }
705
706        // 5. 重新启用FIFO
707        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
708
709        // 6. 恢复UART使能状态
710        if original_cr.is_set(UARTCR::UARTEN) {
711            self.registers().uartcr.modify(
712                UARTCR::UARTEN.val(original_cr.read(UARTCR::UARTEN))
713                    + UARTCR::TXE.val(original_cr.read(UARTCR::TXE))
714                    + UARTCR::RXE.val(original_cr.read(UARTCR::RXE)),
715            );
716        }
717
718        Ok(())
719    }
720
721    fn read_rx(&mut self) -> Option<RxSample> {
722        Pl011::read_rx(self)
723    }
724
725    fn write_tx(&mut self, bytes: &[u8]) -> usize {
726        let mut written = 0;
727        for &byte in bytes {
728            if self.registers().uartfr.is_set(UARTFR::TXFF) {
729                break;
730            }
731            self.registers().uartdr.set(byte as u32);
732            written += 1;
733        }
734        written
735    }
736
737    fn tx_idle(&mut self) -> bool {
738        let fr = self.registers().uartfr.extract();
739        !fr.is_set(UARTFR::BUSY) && !fr.is_set(UARTFR::TXFF)
740    }
741
742    fn mask_all(&mut self) {
743        self.registers().uartimsc.set(0);
744    }
745
746    fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
747        let enabled = self.registers().uartimsc.get() | imsc_for_events(sources);
748        self.registers().uartimsc.set(enabled);
749
750        let fr = self.registers().uartfr.extract();
751        let rsr = self.registers().uartrsr_ecr.extract();
752        let mut ready = SerialEventSet::empty();
753        if sources.intersects(SerialEventSet::RX) && !fr.is_set(UARTFR::RXFE) {
754            ready |= SerialEventSet::RX_DATA;
755        }
756        if sources.contains(SerialEventSet::RX_STATUS) && !Pl011RxStatus::from_rsr(rsr).is_empty() {
757            ready |= SerialEventSet::RX_STATUS;
758        }
759        if sources.contains(SerialEventSet::TX_SPACE) && !fr.is_set(UARTFR::TXFF) {
760            ready |= SerialEventSet::TX_SPACE;
761        }
762        if !ready.is_empty() {
763            self.registers()
764                .uartimsc
765                .set(enabled & !imsc_for_events(ready));
766        }
767        ready
768    }
769}
770
771impl SplitUart for Pl011 {
772    type Port = Self;
773    type Irq = Pl011Irq;
774
775    fn runtime_info(&self) -> UartInfo {
776        UartInfo {
777            name: "PL011 UART",
778            register_base: self.base.0.as_ptr() as usize,
779            initial_baudrate: self.current_baudrate(),
780        }
781    }
782
783    fn split(self) -> UartParts<Self::Port, Self::Irq> {
784        let irq = Pl011Irq {
785            base: self.base,
786            saved_rx_status: Pl011RxStatus::empty(),
787        };
788        UartParts::new(self, irq)
789    }
790}
791
792impl PollingUart for Pl011 {
793    fn poll_status(&mut self) -> SerialEvent {
794        Pl011::poll_status(self)
795    }
796
797    fn write_byte(&mut self, byte: u8) {
798        Pl011::write_byte(self, byte);
799    }
800
801    fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
802        Pl011::read_byte(self, status)
803    }
804}
805
806fn events_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> SerialEventSet {
807    let mut events = SerialEventSet::empty();
808    if mis.is_set(UARTIS::RX) {
809        events |= SerialEventSet::RX_DATA;
810    }
811    if mis.is_set(UARTIS::RT) {
812        events |= SerialEventSet::RX_TIMEOUT;
813    }
814    if mis.is_set(UARTIS::FE)
815        || mis.is_set(UARTIS::PE)
816        || mis.is_set(UARTIS::BE)
817        || mis.is_set(UARTIS::OE)
818    {
819        events |= SerialEventSet::RX_STATUS;
820    }
821    if mis.is_set(UARTIS::TX) {
822        events |= SerialEventSet::TX_SPACE;
823    }
824    if mis.is_set(UARTIS::CTSM)
825        || mis.is_set(UARTIS::DSRM)
826        || mis.is_set(UARTIS::DCDM)
827        || mis.is_set(UARTIS::RIM)
828    {
829        events |= SerialEventSet::MODEM_STATUS;
830    }
831    events
832}
833
834fn rx_errors_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> RxErrorFlags {
835    Pl011RxStatus::from_irq_status(mis).to_irq_errors()
836}
837
838fn imsc_for_events(events: SerialEventSet) -> u32 {
839    let mut imsc = 0;
840    if events.intersects(SerialEventSet::RX) {
841        imsc |= UARTIS::RX::SET.value
842            | UARTIS::RT::SET.value
843            | UARTIS::FE::SET.value
844            | UARTIS::PE::SET.value
845            | UARTIS::BE::SET.value
846            | UARTIS::OE::SET.value;
847    }
848    if events.contains(SerialEventSet::TX_SPACE) {
849        imsc |= UARTIS::TX::SET.value;
850    }
851    if events.contains(SerialEventSet::MODEM_STATUS) {
852        imsc |= UARTIS::RIM::SET.value
853            | UARTIS::CTSM::SET.value
854            | UARTIS::DCDM::SET.value
855            | UARTIS::DSRM::SET.value;
856    }
857    imsc
858}
859
860// 额外的便利方法,用于 FIFO 和流控制
861impl Pl011 {
862    /// 启用或禁用 FIFO
863    pub fn enable_fifo(&self, enable: bool) {
864        if enable {
865            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
866        } else {
867            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
868        }
869    }
870
871    /// 设置 FIFO 触发级别
872    pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
873        // PL011 FIFO 触发级别:
874        // 0b000: 1/8 full
875        // 0b001: 1/4 full
876        // 0b010: 1/2 full
877        // 0b011: 3/4 full
878        // 0b100: 7/8 full
879
880        let rx_iflsel = match rx_level {
881            0..=2 => 0b000,  // 1/8
882            3..=4 => 0b001,  // 1/4
883            5..=8 => 0b010,  // 1/2
884            9..=12 => 0b011, // 3/4
885            _ => 0b100,      // 7/8
886        };
887
888        let tx_iflsel = match tx_level {
889            0..=2 => 0b000,  // 1/8
890            3..=4 => 0b001,  // 1/4
891            5..=8 => 0b010,  // 1/2
892            9..=12 => 0b011, // 3/4
893            _ => 0b100,      // 7/8
894        };
895
896        self.registers()
897            .uartifls
898            .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
899    }
900}
901
902// ModemStatus 现在在 lib.rs 中定义,这里只是导出
903
904#[cfg(test)]
905mod tests {
906    use core::ptr::NonNull;
907    use std::{boxed::Box, vec::Vec};
908
909    use super::*;
910
911    #[derive(Default)]
912    struct CollectRx(Vec<RxSample>);
913
914    impl IrqRxSink for CollectRx {
915        fn push(&mut self, sample: RxSample) {
916            self.0.push(sample);
917        }
918    }
919
920    fn handle_irq(irq: &mut impl UartIrq) -> (Option<SerialIrqEvent>, Vec<RxSample>) {
921        let mut rx = CollectRx::default();
922        let event = irq.handle(&mut rx);
923        (event, rx.0)
924    }
925
926    fn pl011_with_registers() -> (Box<Pl011Registers>, Pl011) {
927        let mut regs = Box::new(unsafe { core::mem::zeroed::<Pl011Registers>() });
928        let ptr = NonNull::from(regs.as_mut()).cast::<u8>();
929        let uart = Pl011::new(ptr, 24_000_000);
930        (regs, uart)
931    }
932
933    fn pl011_with_overrun_data() -> (Box<Pl011Registers>, Pl011) {
934        let (regs, uart) = pl011_with_registers();
935        regs.uartdr
936            .set((UARTDR::DATA.val(0xab) + UARTDR::OE::SET).into());
937        (regs, uart)
938    }
939
940    fn write_test_reg(regs: &mut Pl011Registers, offset: usize, value: u32) {
941        unsafe {
942            (regs as *mut Pl011Registers)
943                .cast::<u32>()
944                .add(offset / core::mem::size_of::<u32>())
945                .write_volatile(value);
946        }
947    }
948
949    fn read_test_reg(regs: &Pl011Registers, offset: usize) -> u32 {
950        unsafe {
951            (regs as *const Pl011Registers)
952                .cast::<u32>()
953                .add(offset / core::mem::size_of::<u32>())
954                .read_volatile()
955        }
956    }
957
958    fn started_parts(uart: Pl011) -> UartParts<Pl011, Pl011Irq> {
959        let mut parts = uart.split();
960        parts.port.startup(&Config::new()).unwrap();
961        parts
962    }
963
964    #[test]
965    fn raw_rx_reports_overrun_instead_of_swallowing_it() {
966        let (_regs, mut uart) = pl011_with_overrun_data();
967
968        let mut buf = [0];
969        let err = uart
970            .try_read(&mut buf)
971            .expect_err("overrun must be reported to the caller");
972
973        assert_eq!(buf[0], 0xab);
974        assert_eq!(err.bytes_transferred, 1);
975        assert_eq!(err.kind, TransferError::Overrun(0xab));
976    }
977
978    #[test]
979    fn raw_rx_sample_reports_overrun_instead_of_swallowing_it() {
980        let (mut regs, uart) = pl011_with_overrun_data();
981        let mut parts = uart.split();
982
983        write_test_reg(&mut regs, 0x040, UARTIS::OE::SET.value);
984        let (event, samples) = handle_irq(&mut parts.irq);
985        let event = event.unwrap();
986        assert!(event.events.contains(SerialEventSet::RX_STATUS));
987        assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
988        assert_eq!(
989            samples.len(),
990            256,
991            "the hard IRQ must enforce its RX budget"
992        );
993        let sample = samples[0];
994        assert_eq!(sample.byte, Some(0xab));
995        assert_eq!(sample.flag, RxFlag::Normal);
996        assert!(sample.overrun);
997    }
998
999    #[test]
1000    fn rx_irq_keeps_source_enabled_after_bounded_fifo_drain() {
1001        let (mut regs, uart) = pl011_with_registers();
1002        let mut irq = uart.split().irq;
1003        let rx_mask = imsc_for_events(SerialEventSet::RX);
1004        write_test_reg(&mut regs, 0x038, rx_mask);
1005        write_test_reg(&mut regs, 0x040, UARTIS::RX::SET.value);
1006        write_test_reg(&mut regs, 0x018, 0);
1007        regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1008
1009        let (event, samples) = handle_irq(&mut irq);
1010        let event = event.unwrap();
1011
1012        assert!(event.events.contains(SerialEventSet::RX_DATA));
1013        assert!(!event.rearm.intersects(SerialEventSet::RX));
1014        assert_eq!(samples.len(), 256);
1015        assert_eq!(read_test_reg(&regs, 0x038) & rx_mask, rx_mask);
1016    }
1017
1018    #[test]
1019    fn irq_status_without_rx_byte_is_preserved_after_irq_ack() {
1020        let (mut regs, uart) = pl011_with_registers();
1021        let mut parts = uart.split();
1022
1023        write_test_reg(
1024            &mut regs,
1025            0x040,
1026            UARTIS::OE::SET.value | UARTIS::PE::SET.value,
1027        );
1028        write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1029
1030        let event = handle_irq(&mut parts.irq).0.unwrap();
1031        assert!(event.events.contains(SerialEventSet::RX_STATUS));
1032        assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1033        assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1034        assert!(parts.port.read_rx().is_none());
1035    }
1036
1037    #[test]
1038    fn tx_irq_exposes_space_without_owning_a_software_fifo() {
1039        let (mut regs, uart) = pl011_with_registers();
1040        let mut parts = started_parts(uart);
1041
1042        write_test_reg(&mut regs, 0x018, 0);
1043        write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1044        let event = handle_irq(&mut parts.irq).0.unwrap();
1045        assert!(event.events.contains(SerialEventSet::TX_SPACE));
1046        assert_eq!(parts.port.write_tx(b"x"), 1);
1047        assert_eq!(regs.uartdr.get() as u8, b'x');
1048    }
1049
1050    #[test]
1051    fn tx_irq_endpoint_acknowledges_tx_interrupt() {
1052        let (mut regs, uart) = pl011_with_registers();
1053        let mut irq = uart.split().irq;
1054
1055        write_test_reg(&mut regs, 0x000, 0x5a);
1056        write_test_reg(&mut regs, 0x038, UARTIS::TX::SET.value);
1057        write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1058        let event = handle_irq(&mut irq).0.unwrap();
1059
1060        assert!(event.events.contains(SerialEventSet::TX_SPACE));
1061        assert_eq!(event.rearm, SerialEventSet::TX_SPACE);
1062        assert_eq!(
1063            read_test_reg(&regs, 0x044) & UARTIS::TX::SET.value,
1064            UARTIS::TX::SET.value
1065        );
1066        assert_eq!(read_test_reg(&regs, 0x038) & UARTIS::TX::SET.value, 0);
1067        assert_eq!(read_test_reg(&regs, 0x000), 0x5a);
1068    }
1069
1070    #[test]
1071    fn set_config_preserves_enabled_tx_and_rx_paths() {
1072        let (regs, mut uart) = pl011_with_registers();
1073        regs.uartcr
1074            .write(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
1075
1076        uart.set_config(&Config::new()).unwrap();
1077
1078        let cr = regs.uartcr.extract();
1079        assert!(cr.is_set(UARTCR::UARTEN));
1080        assert!(cr.is_set(UARTCR::TXE));
1081        assert!(cr.is_set(UARTCR::RXE));
1082    }
1083
1084    #[test]
1085    fn rx_available_mask_enables_timeout_and_error_interrupts() {
1086        let (regs, mut uart) = pl011_with_registers();
1087
1088        uart.set_irq_mask(SerialEventSet::RX);
1089
1090        let imsc = regs.uartimsc.extract();
1091        assert!(imsc.is_set(UARTIS::RX));
1092        assert!(imsc.is_set(UARTIS::RT));
1093        assert!(imsc.is_set(UARTIS::FE));
1094        assert!(imsc.is_set(UARTIS::PE));
1095        assert!(imsc.is_set(UARTIS::BE));
1096        assert!(imsc.is_set(UARTIS::OE));
1097        assert_eq!(uart.get_irq_mask(), SerialEventSet::RX);
1098    }
1099
1100    #[test]
1101    fn hard_irq_does_not_claim_rx_ready_without_mis() {
1102        let (mut regs, uart) = pl011_with_registers();
1103        let mut parts = uart.split();
1104
1105        parts.port.set_irq_mask(SerialEventSet::RX);
1106        write_test_reg(&mut regs, 0x040, 0);
1107        write_test_reg(&mut regs, 0x018, 0);
1108
1109        assert!(handle_irq(&mut parts.irq).0.is_none());
1110    }
1111
1112    #[test]
1113    fn port_rx_ready_is_visible_without_irq_event() {
1114        let (mut regs, mut uart) = pl011_with_registers();
1115
1116        uart.set_irq_mask(SerialEventSet::RX);
1117        write_test_reg(&mut regs, 0x040, 0);
1118        write_test_reg(&mut regs, 0x018, 0);
1119        regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1120
1121        let status = uart.poll_status();
1122        assert!(status.rx_ready());
1123        let sample = uart.read_rx().expect("RX sample should be available");
1124        assert_eq!(sample.byte, Some(b'r'));
1125        assert_eq!(sample.flag, RxFlag::Normal);
1126    }
1127
1128    #[test]
1129    fn rearm_remasks_rx_when_fifo_is_already_ready() {
1130        let (mut regs, mut uart) = pl011_with_registers();
1131        write_test_reg(&mut regs, 0x018, 0);
1132
1133        let ready = uart.rearm(SerialEventSet::RX);
1134
1135        assert_eq!(ready, SerialEventSet::RX_DATA);
1136        assert_eq!(
1137            read_test_reg(&regs, 0x038) & imsc_for_events(SerialEventSet::RX),
1138            0
1139        );
1140    }
1141
1142    #[test]
1143    fn unknown_irq_source_masks_all_without_fifo_access() {
1144        let (mut regs, uart) = pl011_with_registers();
1145        let mut irq = uart.split().irq;
1146        write_test_reg(&mut regs, 0x000, 0x5a);
1147        write_test_reg(&mut regs, 0x038, u32::MAX);
1148        write_test_reg(&mut regs, 0x040, 1 << 31);
1149
1150        let event = handle_irq(&mut irq).0.unwrap();
1151
1152        assert!(event.events.contains(SerialEventSet::FAULT));
1153        assert_eq!(read_test_reg(&regs, 0x038), 0);
1154        assert_eq!(read_test_reg(&regs, 0x000), 0x5a);
1155    }
1156}