Skip to main content

some_serial/
pl011.rs

1use core::ptr::NonNull;
2
3use rdif_serial::{
4    Config, ConfigError, DataBits, IRQ_RX_BATCH_CAPACITY, IrqRxBatch, Parity, RxErrorFlags, RxFlag,
5    RxSample, SerialEventSet, SerialIrqEvent, SerialIrqReport, SerialParts, SplitUart, StopBits,
6    UartEmergencyTx, UartInfo, UartIrq, UartPort,
7};
8use tock_registers::{
9    LocalRegisterCopy, interfaces::*, register_bitfields, register_structs, registers::*,
10};
11
12use crate::{PollingUart, SerialDirection, SerialEvent, TransBytesError, TransferError};
13
14const OPEN_BUSY_POLL_BUDGET: usize = 1 << 20;
15const EMERGENCY_TX_BUDGET: usize = 16;
16
17register_bitfields! [
18    u32,
19
20    /// Data Register
21    UARTDR [
22        DATA OFFSET(0) NUMBITS(8) [],
23        FE OFFSET(8) NUMBITS(1) [],
24        PE OFFSET(9) NUMBITS(1) [],
25        BE OFFSET(10) NUMBITS(1) [],
26        OE OFFSET(11) NUMBITS(1) []
27    ],
28
29    /// Receive Status Register / Error Clear Register
30    UARTRSR_ECR [
31        FE OFFSET(0) NUMBITS(1) [],
32        PE OFFSET(1) NUMBITS(1) [],
33        BE OFFSET(2) NUMBITS(1) [],
34        OE OFFSET(3) NUMBITS(1) []
35    ],
36
37    /// Flag Register
38    UARTFR [
39        CTS OFFSET(0) NUMBITS(1) [],
40        DSR OFFSET(1) NUMBITS(1) [],
41        DCD OFFSET(2) NUMBITS(1) [],
42        BUSY OFFSET(3) NUMBITS(1) [],
43        RXFE OFFSET(4) NUMBITS(1) [],
44        TXFF OFFSET(5) NUMBITS(1) [],
45        RXFF OFFSET(6) NUMBITS(1) [],
46        TXFE OFFSET(7) NUMBITS(1) [],
47        RI OFFSET(8) NUMBITS(1) []
48    ],
49
50    /// Integer Baud Rate Register
51    UARTIBRD [
52        BAUD_DIVINT OFFSET(0) NUMBITS(16) []
53    ],
54
55    /// Fractional Baud Rate Register
56    UARTFBRD [
57        BAUD_DIVFRAC OFFSET(0) NUMBITS(6) []
58    ],
59
60    /// Line Control Register
61    UARTLCR_H [
62        BRK OFFSET(0) NUMBITS(1) [],
63        PEN OFFSET(1) NUMBITS(1) [],
64        EPS OFFSET(2) NUMBITS(1) [],
65        STP2 OFFSET(3) NUMBITS(1) [],
66        FEN OFFSET(4) NUMBITS(1) [],
67        WLEN OFFSET(5) NUMBITS(2) [
68            FiveBit = 0,
69            SixBit = 1,
70            SevenBit = 2,
71            EightBit = 3
72        ],
73        SPS OFFSET(7) NUMBITS(1) []
74    ],
75
76    /// Control Register
77    UARTCR [
78        UARTEN OFFSET(0) NUMBITS(1) [],
79        SIREN OFFSET(1) NUMBITS(1) [],
80        SIRLP OFFSET(2) NUMBITS(1) [],
81        LBE OFFSET(7) NUMBITS(1) [],
82        TXE OFFSET(8) NUMBITS(1) [],
83        RXE OFFSET(9) NUMBITS(1) [],
84        DTR OFFSET(10) NUMBITS(1) [],
85        RTS OFFSET(11) NUMBITS(1) [],
86        OUT1 OFFSET(12) NUMBITS(1) [],
87        OUT2 OFFSET(13) NUMBITS(1) [],
88        RTSEN OFFSET(14) NUMBITS(1) [],
89        CTSEN OFFSET(15) NUMBITS(1) []
90    ],
91
92    /// Interrupt FIFO Level Select Register
93    UARTIFLS [
94        TXIFLSEL OFFSET(0) NUMBITS(3) [],
95        RXIFLSEL OFFSET(3) NUMBITS(3) []
96    ],
97
98    /// Interrupt Mask Set/Clear Register
99    UARTIS [
100        RIM OFFSET(0) NUMBITS(1) [],
101        CTSM OFFSET(1) NUMBITS(1) [],
102        DCDM OFFSET(2) NUMBITS(1) [],
103        DSRM OFFSET(3) NUMBITS(1) [],
104        RX OFFSET(4) NUMBITS(1) [],
105        TX OFFSET(5) NUMBITS(1) [],
106        RT OFFSET(6) NUMBITS(1) [],
107        FE OFFSET(7) NUMBITS(1) [],
108        PE OFFSET(8) NUMBITS(1) [],
109        BE OFFSET(9) NUMBITS(1) [],
110        OE OFFSET(10) NUMBITS(1) []
111    ],
112
113    /// DMA Control Register
114    UARTDMACR [
115        RXDMAE OFFSET(0) NUMBITS(1) [],
116        TXDMAE OFFSET(1) NUMBITS(1) [],
117        DMAONERR OFFSET(2) NUMBITS(1) []
118    ]
119];
120
121register_structs! {
122    pub Pl011Registers {
123        (0x000 => uartdr: ReadWrite<u32, UARTDR::Register>),        // 数据寄存器(收发数据/错误标志)
124        (0x004 => uartrsr_ecr: ReadWrite<u32, UARTRSR_ECR::Register>), // 接收状态/错误清除寄存器
125        (0x008 => _reserved1),                                      // 保留
126        (0x018 => uartfr: ReadOnly<u32, UARTFR::Register>),         // 标志寄存器(状态标志,如忙/空/满等)
127        (0x01c => _reserved2),                                      // 保留
128        (0x020 => uartilpr: ReadWrite<u32>),                        // 红外低功耗波特率寄存器(很少用)
129        (0x024 => uartibrd: ReadWrite<u32, UARTIBRD::Register>),    // 整数波特率分频寄存器
130        (0x028 => uartfbrd: ReadWrite<u32, UARTFBRD::Register>),    // 小数波特率分频寄存器
131        (0x02c => uartlcr_h: ReadWrite<u32, UARTLCR_H::Register>),  // 线路控制寄存器(数据位、停止位、校验等)
132        (0x030 => uartcr: ReadWrite<u32, UARTCR::Register>),        // 控制寄存器(UART使能、收发使能等)
133        (0x034 => uartifls: ReadWrite<u32, UARTIFLS::Register>),    // FIFO中断触发级别选择寄存器
134        (0x038 => uartimsc: ReadWrite<u32, UARTIS::Register>),      // 中断屏蔽设置/清除寄存器
135        (0x03c => uartris: ReadOnly<u32, UARTIS::Register>),        // 原始中断状态寄存器
136        (0x040 => uartmis: ReadOnly<u32, UARTIS::Register>),        // 屏蔽后的中断状态寄存器
137        (0x044 => uarticr: WriteOnly<u32, UARTIS::Register>),       // 中断清除寄存器
138        (0x048 => uartdmacr: ReadWrite<u32, UARTDMACR::Register>),  // DMA控制寄存器
139        (0x04c => _reserved3),                                      // 保留
140        (0x1000 => @END),
141    }
142}
143
144// SAFETY: PL011 寄存器访问是原子的,硬件保证了内存映射寄存器的线程安全
145unsafe impl Sync for Pl011Registers {}
146
147/// PL011 UART 驱动结构体
148pub struct Pl011 {
149    base: Reg,
150    clock_freq: u32,
151    saved_rx_status: Pl011RxStatus,
152}
153
154#[derive(Clone, Copy)]
155struct Pl011ConfigSnapshot {
156    ilpr: u32,
157    ibrd: u32,
158    fbrd: u32,
159    lcr_h: u32,
160    cr: u32,
161    ifls: u32,
162    imsc: u32,
163    dmacr: u32,
164}
165
166impl Pl011ConfigSnapshot {
167    fn capture(registers: &Pl011Registers) -> Self {
168        Self {
169            ilpr: registers.uartilpr.get(),
170            ibrd: registers.uartibrd.get(),
171            fbrd: registers.uartfbrd.get(),
172            lcr_h: registers.uartlcr_h.get(),
173            cr: registers.uartcr.get(),
174            ifls: registers.uartifls.get(),
175            imsc: registers.uartimsc.get(),
176            dmacr: registers.uartdmacr.get(),
177        }
178    }
179
180    fn restore(self, registers: &Pl011Registers) {
181        registers.uartilpr.set(self.ilpr);
182        registers.uartibrd.set(self.ibrd);
183        registers.uartfbrd.set(self.fbrd);
184        registers.uartlcr_h.set(self.lcr_h);
185        registers.uartifls.set(self.ifls);
186        registers.uartimsc.set(self.imsc);
187        registers.uartdmacr.set(self.dmacr);
188        // Restore CR last so the original enable state is not published until
189        // every dependent configuration register is back in place.
190        registers.uartcr.set(self.cr);
191    }
192}
193
194impl Pl011 {
195    /// 创建新的 PL011 实例(仅基地址,使用默认配置)
196    ///
197    /// # Arguments
198    /// * `base` - UART 寄存器基地址
199    pub fn new_no_clock(base: NonNull<u8>) -> Self {
200        // 自动检测时钟频率或使用合理的默认值
201        let clock_freq = Self::detect_clock_frequency(base.as_ptr() as usize);
202        Self::new(base, clock_freq)
203    }
204
205    pub fn new(base: NonNull<u8>, clock_freq: u32) -> Self {
206        let base = Reg(base.cast());
207
208        Self {
209            base,
210            clock_freq,
211            saved_rx_status: Pl011RxStatus::empty(),
212        }
213    }
214
215    fn registers(&self) -> &Pl011Registers {
216        unsafe { &*self.base.0.as_ptr() }
217    }
218
219    fn wait_until_idle(&self) -> bool {
220        for _ in 0..OPEN_BUSY_POLL_BUDGET {
221            if !self.registers().uartfr.is_set(UARTFR::BUSY) {
222                return true;
223            }
224            core::hint::spin_loop();
225        }
226        false
227    }
228
229    fn current_baudrate(&self) -> u32 {
230        let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
231        let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
232        let divisor = ibrd * 64 + fbrd;
233        if divisor == 0 {
234            0
235        } else {
236            self.clock_freq * 64 / (16 * divisor)
237        }
238    }
239
240    /// 自动检测或确定合理的时钟频率
241    fn detect_clock_frequency(base: usize) -> u32 {
242        // 尝试读取当前波特率设置来反向推算时钟频率
243        let registers = unsafe { &*(base as *const Pl011Registers) };
244
245        use tock_registers::interfaces::Readable;
246        let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
247
248        // 如果有设置值,假设波特率为 115200 来估算时钟频率
249        if ibrd > 0 && ibrd <= 0xFFFF {
250            // 假设波特率为 115200,计算时钟频率
251            // FUARTCLK = 16 * BAUDDIV * Baud rate
252            let estimated_clock = 16 * ibrd * 115200;
253
254            // 合理的时钟频率范围:1MHz - 100MHz
255            if (1_000_000..=100_000_000).contains(&estimated_clock) {
256                return estimated_clock;
257            }
258        }
259
260        // 默认使用 24MHz(最常见)
261        24_000_000
262    }
263
264    // 内部私有方法,用于配置
265    fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
266        // PL011 波特率计算公式:
267        // BAUDDIV = (FUARTCLK / (16 * Baud rate))
268        // IBRD = integer(BAUDDIV)
269        // FBRD = integer((BAUDDIV - IBRD) * 64 + 0.5)
270
271        let scaled_baudrate = baudrate
272            .checked_mul(16)
273            .filter(|scaled| *scaled != 0)
274            .ok_or(ConfigError::InvalidBaudrate)?;
275        let bauddiv = self.clock_freq / scaled_baudrate;
276        let remainder = self.clock_freq % scaled_baudrate;
277        let fbrd = (remainder * 64 + scaled_baudrate / 2) / scaled_baudrate;
278
279        if bauddiv == 0 || bauddiv > 0xFFFF {
280            return Err(ConfigError::InvalidBaudrate);
281        }
282
283        self.registers()
284            .uartibrd
285            .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
286        self.registers()
287            .uartfbrd
288            .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
289
290        Ok(())
291    }
292
293    fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
294        let wlen = match bits {
295            DataBits::Five => UARTLCR_H::WLEN::FiveBit,
296            DataBits::Six => UARTLCR_H::WLEN::SixBit,
297            DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
298            DataBits::Eight => UARTLCR_H::WLEN::EightBit,
299        };
300
301        self.registers().uartlcr_h.modify(wlen);
302        Ok(())
303    }
304
305    fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
306        match bits {
307            StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
308            StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
309        }
310
311        Ok(())
312    }
313
314    fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
315        match parity {
316            Parity::None => {
317                // PEN = 0, 无奇偶校验
318                self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
319            }
320            Parity::Odd => {
321                // PEN = 1, EPS = 0 (奇校验), SPS = 0
322                self.registers()
323                    .uartlcr_h
324                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
325            }
326            Parity::Even => {
327                // PEN = 1, EPS = 1 (偶校验), SPS = 0
328                self.registers()
329                    .uartlcr_h
330                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
331            }
332            Parity::Mark => {
333                // PEN = 1, SPS = 1, EPS = 0 (奇校验)
334                self.registers()
335                    .uartlcr_h
336                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
337            }
338            Parity::Space => {
339                // PEN = 1, EPS = 1 (偶校验), SPS = 1
340                self.registers()
341                    .uartlcr_h
342                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
343            }
344        }
345
346        Ok(())
347    }
348
349    /// Initializes the PL011 UART.
350    ///
351    /// Returns [`ConfigError::Timeout`] if an in-flight transfer does not
352    /// finish within the fixed early-boot polling budget.
353    pub fn open(&mut self) -> Result<(), ConfigError> {
354        let snapshot = Pl011ConfigSnapshot::capture(self.registers());
355
356        // 禁用 UART
357        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
358
359        // 等待当前传输完成
360        if !self.wait_until_idle() {
361            snapshot.restore(self.registers());
362            return Err(ConfigError::Timeout);
363        }
364
365        // 清除发送 FIFO
366        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
367
368        // 启用 FIFO
369        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
370
371        // 调试信息:输出 FIFO 配置
372        #[cfg(debug_assertions)]
373        {
374            let ifls = self.registers().uartifls.get();
375            let lcr_h = self.registers().uartlcr_h.get();
376            log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
377            log::debug!("  FIFO enabled: {}", lcr_h & (1 << 4) != 0);
378            log::debug!("  RX trigger level: 1/8");
379            log::debug!("  TX trigger level: 1/2");
380        }
381        self.registers().uartimsc.set(0); // 禁用所有中断
382        // 启用 UART
383        self.registers()
384            .uartcr
385            .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
386        Ok(())
387    }
388
389    pub fn set_irq_mask(&mut self, events: SerialEventSet) {
390        self.registers().uartimsc.set(imsc_for_events(events));
391    }
392
393    pub fn get_irq_mask(&self) -> SerialEventSet {
394        let imsc = self.registers().uartimsc.extract();
395        let mut events = SerialEventSet::empty();
396
397        if imsc.is_set(UARTIS::RX)
398            || imsc.is_set(UARTIS::RT)
399            || imsc.is_set(UARTIS::FE)
400            || imsc.is_set(UARTIS::PE)
401            || imsc.is_set(UARTIS::BE)
402            || imsc.is_set(UARTIS::OE)
403        {
404            events |= SerialEventSet::RX;
405        }
406        if imsc.is_set(UARTIS::TX) {
407            events |= SerialEventSet::TX_SPACE;
408        }
409
410        events
411    }
412
413    pub fn pending(&mut self, direction: SerialDirection) -> bool {
414        match direction {
415            SerialDirection::Input => !self.registers().uartfr.is_set(UARTFR::RXFE),
416            SerialDirection::Output => !self.registers().uartfr.is_set(UARTFR::TXFF),
417        }
418    }
419
420    pub fn poll_status(&mut self) -> SerialEvent {
421        let mut event = SerialEvent::empty();
422        let fr = self.registers().uartfr.extract();
423        if !fr.is_set(UARTFR::RXFE) {
424            event |= SerialEvent::RX_READY;
425        }
426        if !fr.is_set(UARTFR::TXFF) {
427            event |= SerialEvent::TX_READY;
428        }
429
430        let status =
431            self.saved_rx_status | Pl011RxStatus::from_rsr(self.registers().uartrsr_ecr.extract());
432        if status.intersects(Pl011RxStatus::FRAMING | Pl011RxStatus::PARITY | Pl011RxStatus::BREAK)
433        {
434            event |= SerialEvent::RX_ERROR;
435        }
436        if status.contains(Pl011RxStatus::OVERRUN) {
437            event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
438        }
439
440        event
441    }
442
443    pub fn try_write(&mut self, bytes: &[u8]) -> usize {
444        let mut written = 0;
445        for &byte in bytes {
446            let status = self.poll_status();
447            if !status.tx_ready() {
448                break;
449            }
450            self.write_byte(byte);
451            written += 1;
452        }
453        written
454    }
455
456    pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
457        let mut count = 0;
458        for byte in bytes.iter_mut() {
459            let status = self.poll_status();
460            if !status.rx_ready() && !status.rx_error() {
461                break;
462            }
463            match self.read_byte(status) {
464                Some(Ok(b)) => {
465                    *byte = b;
466                }
467                Some(Err(TransferError::Overrun(b))) => {
468                    *byte = b;
469                    count += 1;
470                    return Err(TransBytesError {
471                        bytes_transferred: count,
472                        kind: TransferError::Overrun(b),
473                    });
474                }
475                Some(Err(e)) => {
476                    return Err(TransBytesError {
477                        bytes_transferred: count,
478                        kind: e,
479                    });
480                }
481                None => break,
482            }
483            count += 1;
484        }
485        Ok(count)
486    }
487
488    pub fn write_byte(&mut self, byte: u8) {
489        self.registers().uartdr.set(byte as _);
490    }
491
492    pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
493        if !status.rx_ready() && !status.rx_error() {
494            return None;
495        }
496
497        let sample = self.read_rx()?;
498        if sample.overrun {
499            return Some(Err(TransferError::Overrun(sample.byte.unwrap_or(0))));
500        }
501        match sample.flag {
502            RxFlag::Normal => sample.byte.map(Ok),
503            RxFlag::Break => Some(Err(TransferError::Break)),
504            RxFlag::Parity => Some(Err(TransferError::Parity)),
505            RxFlag::Framing => Some(Err(TransferError::Framing)),
506        }
507    }
508
509    pub fn read_rx(&mut self) -> Option<RxSample> {
510        let base = self.base;
511        // SAFETY: `base` is the mapped PL011 register block owned by this
512        // endpoint and remains valid for the endpoint lifetime.
513        let registers = unsafe { &*base.0.as_ptr() };
514        read_rx_sample(registers, &mut self.saved_rx_status)
515    }
516}
517
518fn read_rx_sample(
519    registers: &Pl011Registers,
520    saved_status: &mut Pl011RxStatus,
521) -> Option<RxSample> {
522    if registers.uartfr.is_set(UARTFR::RXFE) {
523        *saved_status |= Pl011RxStatus::from_rsr(registers.uartrsr_ecr.extract());
524        return saved_status.take_status_sample();
525    }
526
527    let dr = registers.uartdr.extract();
528    let data = dr.read(UARTDR::DATA) as u8;
529    let status = Pl011RxStatus::from_data(dr);
530    if !status.is_empty() {
531        saved_status.remove(status);
532    }
533
534    Some(RxSample {
535        byte: Some(data),
536        flag: status.flag(),
537        overrun: status.contains(Pl011RxStatus::OVERRUN),
538    })
539}
540
541fn rx_errors_from_sample(sample: RxSample) -> RxErrorFlags {
542    let mut errors = match sample.flag {
543        RxFlag::Normal => RxErrorFlags::empty(),
544        RxFlag::Break => RxErrorFlags::BREAK,
545        RxFlag::Parity => RxErrorFlags::PARITY,
546        RxFlag::Framing => RxErrorFlags::FRAMING,
547    };
548    if sample.overrun {
549        errors |= RxErrorFlags::OVERRUN;
550    }
551    errors
552}
553
554bitflags::bitflags! {
555    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
556    struct Pl011RxStatus: u32 {
557        const FRAMING = 1 << 0;
558        const PARITY  = 1 << 1;
559        const BREAK   = 1 << 2;
560        const OVERRUN = 1 << 3;
561    }
562}
563
564impl Pl011RxStatus {
565    fn to_irq_errors(self) -> RxErrorFlags {
566        let mut errors = RxErrorFlags::empty();
567        if self.contains(Self::BREAK) {
568            errors |= RxErrorFlags::BREAK;
569        }
570        if self.contains(Self::PARITY) {
571            errors |= RxErrorFlags::PARITY;
572        }
573        if self.contains(Self::FRAMING) {
574            errors |= RxErrorFlags::FRAMING;
575        }
576        if self.contains(Self::OVERRUN) {
577            errors |= RxErrorFlags::OVERRUN;
578        }
579        errors
580    }
581
582    fn from_data(dr: LocalRegisterCopy<u32, UARTDR::Register>) -> Self {
583        let mut status = Self::empty();
584        if dr.is_set(UARTDR::FE) {
585            status |= Self::FRAMING;
586        }
587        if dr.is_set(UARTDR::PE) {
588            status |= Self::PARITY;
589        }
590        if dr.is_set(UARTDR::BE) {
591            status |= Self::BREAK;
592        }
593        if dr.is_set(UARTDR::OE) {
594            status |= Self::OVERRUN;
595        }
596        status
597    }
598
599    fn from_irq_status(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> Self {
600        let mut status = Self::empty();
601        if mis.is_set(UARTIS::FE) {
602            status |= Self::FRAMING;
603        }
604        if mis.is_set(UARTIS::PE) {
605            status |= Self::PARITY;
606        }
607        if mis.is_set(UARTIS::BE) {
608            status |= Self::BREAK;
609        }
610        if mis.is_set(UARTIS::OE) {
611            status |= Self::OVERRUN;
612        }
613        status
614    }
615
616    fn from_rsr(rsr: LocalRegisterCopy<u32, UARTRSR_ECR::Register>) -> Self {
617        let mut status = Self::empty();
618        if rsr.is_set(UARTRSR_ECR::FE) {
619            status |= Self::FRAMING;
620        }
621        if rsr.is_set(UARTRSR_ECR::PE) {
622            status |= Self::PARITY;
623        }
624        if rsr.is_set(UARTRSR_ECR::BE) {
625            status |= Self::BREAK;
626        }
627        if rsr.is_set(UARTRSR_ECR::OE) {
628            status |= Self::OVERRUN;
629        }
630        status
631    }
632
633    fn flag(self) -> RxFlag {
634        if self.contains(Self::BREAK) {
635            RxFlag::Break
636        } else if self.contains(Self::PARITY) {
637            RxFlag::Parity
638        } else if self.contains(Self::FRAMING) {
639            RxFlag::Framing
640        } else {
641            RxFlag::Normal
642        }
643    }
644
645    fn take_status_sample(&mut self) -> Option<RxSample> {
646        if self.is_empty() {
647            return None;
648        }
649
650        let status = *self;
651        *self = Self::empty();
652        Some(RxSample {
653            byte: None,
654            flag: status.flag(),
655            overrun: status.contains(Self::OVERRUN),
656        })
657    }
658}
659
660#[derive(Clone, Copy, PartialEq, Eq)]
661struct Reg(NonNull<Pl011Registers>);
662
663unsafe impl Send for Reg {}
664unsafe impl Sync for Reg {}
665
666/// IRQ-only endpoint for a PL011 UART.
667pub struct Pl011Irq {
668    base: Reg,
669    saved_rx_status: Pl011RxStatus,
670}
671
672/// Restricted non-blocking TX view used only for emergency output.
673pub struct Pl011EmergencyTx {
674    base: Reg,
675}
676
677impl Pl011EmergencyTx {
678    fn registers(&self) -> &Pl011Registers {
679        // SAFETY: `base` points at the mapped PL011 register block. This view
680        // exposes only the TX FIFO readiness and data registers.
681        unsafe { &*self.base.0.as_ptr() }
682    }
683
684    fn mask_interrupts(&self) {
685        self.registers().uartimsc.set(0);
686        // Flush a posted MMIO write before the emergency path touches TX.
687        let _masked = self.registers().uartimsc.get();
688    }
689}
690
691impl UartEmergencyTx for Pl011EmergencyTx {
692    unsafe fn mask_interrupts_unlocked(&self) {
693        self.mask_interrupts();
694    }
695
696    unsafe fn try_write_unlocked(&self, bytes: &[u8]) -> usize {
697        let mut written = 0;
698        for &byte in bytes.iter().take(EMERGENCY_TX_BUDGET) {
699            if self.registers().uartfr.is_set(UARTFR::TXFF) {
700                break;
701            }
702            self.registers().uartdr.set(byte as u32);
703            written += 1;
704        }
705        written
706    }
707}
708
709impl Pl011Irq {
710    fn registers(&self) -> &Pl011Registers {
711        // SAFETY: `base` points at the mapped PL011 register block. The IRQ
712        // endpoint intentionally exposes no FIFO data methods.
713        unsafe { &*self.base.0.as_ptr() }
714    }
715}
716
717impl UartIrq for Pl011Irq {
718    fn mask(&mut self, sources: SerialEventSet) {
719        let enabled = self.registers().uartimsc.get();
720        self.registers()
721            .uartimsc
722            .set(enabled & !imsc_for_events(sources));
723    }
724
725    fn handle(&mut self) -> Option<SerialIrqReport> {
726        let mis = self.registers().uartmis.extract();
727        let active = mis.get();
728        if active == 0 {
729            return None;
730        }
731
732        let mut events = events_from_mis(mis);
733        let mut rx = IrqRxBatch::new();
734        if active & !0x7ff != 0 {
735            events |= SerialEventSet::FAULT;
736        }
737        let mut rx_errors = rx_errors_from_mis(mis);
738        if events.intersects(SerialEventSet::RX) {
739            let base = self.base;
740            // SAFETY: `base` is the mapped PL011 register block shared with
741            // the task endpoint under the runtime's same-CPU exclusion rule.
742            let registers = unsafe { &*base.0.as_ptr() };
743            for _ in 0..IRQ_RX_BATCH_CAPACITY {
744                let Some(sample) = read_rx_sample(registers, &mut self.saved_rx_status) else {
745                    break;
746                };
747                rx_errors |= rx_errors_from_sample(sample);
748                rx.try_push(sample)
749                    .expect("the fixed PL011 IRQ loop cannot overflow its RX batch");
750            }
751        }
752
753        let mut rearm = events & SerialEventSet::TX_SPACE;
754        if rx.len() == IRQ_RX_BATCH_CAPACITY || rx_errors.contains(RxErrorFlags::OVERRUN) {
755            rearm |= SerialEventSet::RX;
756        }
757        if events.contains(SerialEventSet::FAULT) {
758            self.registers().uartimsc.set(0);
759        } else if !rearm.is_empty() {
760            self.mask(rearm);
761        }
762        self.registers().uarticr.set(active);
763
764        Some(SerialIrqReport::new(
765            SerialIrqEvent {
766                events,
767                rx_errors,
768                rearm,
769            },
770            rx,
771        ))
772    }
773}
774
775impl UartPort for Pl011 {
776    fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
777        let snapshot = Pl011ConfigSnapshot::capture(self.registers());
778        if let Err(error) = self.open().and_then(|()| self.set_config(config)) {
779            snapshot.restore(self.registers());
780            return Err(error);
781        }
782        self.mask_all();
783        Ok(())
784    }
785
786    fn shutdown(&mut self) {
787        self.registers().uartimsc.set(0);
788        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
789    }
790
791    fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
792        let snapshot = Pl011ConfigSnapshot::capture(self.registers());
793        let result = (|| {
794            self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
795            if !self.wait_until_idle() {
796                return Err(ConfigError::Timeout);
797            }
798
799            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
800            if let Some(baudrate) = config.baudrate {
801                self.set_baudrate_internal(baudrate)?;
802            }
803            if let Some(data_bits) = config.data_bits {
804                self.set_data_bits_internal(data_bits)?;
805            }
806            if let Some(stop_bits) = config.stop_bits {
807                self.set_stop_bits_internal(stop_bits)?;
808            }
809            if let Some(parity) = config.parity {
810                self.set_parity_internal(parity)?;
811            }
812            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
813            self.registers().uartcr.set(snapshot.cr);
814            Ok(())
815        })();
816
817        if result.is_err() {
818            snapshot.restore(self.registers());
819        }
820        result
821    }
822
823    fn read_rx(&mut self) -> Option<RxSample> {
824        Pl011::read_rx(self)
825    }
826
827    fn discard_rx(&mut self) {
828        while !self.registers().uartfr.is_set(UARTFR::RXFE) {
829            let _ = self.registers().uartdr.get();
830        }
831        self.saved_rx_status = Pl011RxStatus::empty();
832        self.registers().uartrsr_ecr.set(0);
833        self.registers()
834            .uarticr
835            .set(imsc_for_events(SerialEventSet::RX));
836    }
837
838    fn write_tx(&mut self, bytes: &[u8]) -> usize {
839        let mut written = 0;
840        for &byte in bytes {
841            if self.registers().uartfr.is_set(UARTFR::TXFF) {
842                break;
843            }
844            self.registers().uartdr.set(byte as u32);
845            written += 1;
846        }
847        written
848    }
849
850    fn discard_tx(&mut self) -> bool {
851        false
852    }
853
854    fn tx_idle(&mut self) -> bool {
855        let fr = self.registers().uartfr.extract();
856        !fr.is_set(UARTFR::BUSY) && !fr.is_set(UARTFR::TXFF)
857    }
858
859    fn mask(&mut self, sources: SerialEventSet) {
860        let enabled = self.registers().uartimsc.get();
861        self.registers()
862            .uartimsc
863            .set(enabled & !imsc_for_events(sources));
864    }
865
866    fn mask_all(&mut self) {
867        self.registers().uartimsc.set(0);
868    }
869
870    fn rearm(&mut self, sources: SerialEventSet) -> SerialEventSet {
871        let enabled = self.registers().uartimsc.get() | imsc_for_events(sources);
872        self.registers().uartimsc.set(enabled);
873
874        let fr = self.registers().uartfr.extract();
875        let rsr = self.registers().uartrsr_ecr.extract();
876        let mut ready = SerialEventSet::empty();
877        if sources.intersects(SerialEventSet::RX) && !fr.is_set(UARTFR::RXFE) {
878            ready |= SerialEventSet::RX_DATA;
879        }
880        if sources.contains(SerialEventSet::RX_STATUS) && !Pl011RxStatus::from_rsr(rsr).is_empty() {
881            ready |= SerialEventSet::RX_STATUS;
882        }
883        if sources.contains(SerialEventSet::TX_SPACE) && !fr.is_set(UARTFR::TXFF) {
884            ready |= SerialEventSet::TX_SPACE;
885        }
886        if !ready.is_empty() {
887            self.registers()
888                .uartimsc
889                .set(enabled & !imsc_for_events(ready));
890        }
891        ready
892    }
893}
894
895impl SplitUart for Pl011 {
896    type Control = Self;
897    type Irq = Pl011Irq;
898    type EmergencyTx = Pl011EmergencyTx;
899
900    fn runtime_info(&self) -> UartInfo {
901        UartInfo {
902            name: "PL011 UART",
903            register_base: self.base.0.as_ptr() as usize,
904            initial_baudrate: self.current_baudrate(),
905        }
906    }
907
908    fn split(self) -> SerialParts<Self::Control, Self::Irq, Self::EmergencyTx> {
909        let irq = Pl011Irq {
910            base: self.base,
911            saved_rx_status: Pl011RxStatus::empty(),
912        };
913        let emergency_tx = Pl011EmergencyTx { base: self.base };
914        SerialParts::new(self, irq, emergency_tx)
915    }
916}
917
918impl PollingUart for Pl011 {
919    fn poll_status(&mut self) -> SerialEvent {
920        Pl011::poll_status(self)
921    }
922
923    fn write_byte(&mut self, byte: u8) {
924        Pl011::write_byte(self, byte);
925    }
926
927    fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
928        Pl011::read_byte(self, status)
929    }
930}
931
932fn events_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> SerialEventSet {
933    let mut events = SerialEventSet::empty();
934    if mis.is_set(UARTIS::RX) {
935        events |= SerialEventSet::RX_DATA;
936    }
937    if mis.is_set(UARTIS::RT) {
938        events |= SerialEventSet::RX_TIMEOUT;
939    }
940    if mis.is_set(UARTIS::FE)
941        || mis.is_set(UARTIS::PE)
942        || mis.is_set(UARTIS::BE)
943        || mis.is_set(UARTIS::OE)
944    {
945        events |= SerialEventSet::RX_STATUS;
946    }
947    if mis.is_set(UARTIS::TX) {
948        events |= SerialEventSet::TX_SPACE;
949    }
950    if mis.is_set(UARTIS::CTSM)
951        || mis.is_set(UARTIS::DSRM)
952        || mis.is_set(UARTIS::DCDM)
953        || mis.is_set(UARTIS::RIM)
954    {
955        events |= SerialEventSet::MODEM_STATUS;
956    }
957    events
958}
959
960fn rx_errors_from_mis(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> RxErrorFlags {
961    Pl011RxStatus::from_irq_status(mis).to_irq_errors()
962}
963
964fn imsc_for_events(events: SerialEventSet) -> u32 {
965    let mut imsc = 0;
966    if events.intersects(SerialEventSet::RX) {
967        imsc |= UARTIS::RX::SET.value
968            | UARTIS::RT::SET.value
969            | UARTIS::FE::SET.value
970            | UARTIS::PE::SET.value
971            | UARTIS::BE::SET.value
972            | UARTIS::OE::SET.value;
973    }
974    if events.contains(SerialEventSet::TX_SPACE) {
975        imsc |= UARTIS::TX::SET.value;
976    }
977    if events.contains(SerialEventSet::MODEM_STATUS) {
978        imsc |= UARTIS::RIM::SET.value
979            | UARTIS::CTSM::SET.value
980            | UARTIS::DCDM::SET.value
981            | UARTIS::DSRM::SET.value;
982    }
983    imsc
984}
985
986// 额外的便利方法,用于 FIFO 和流控制
987impl Pl011 {
988    /// 启用或禁用 FIFO
989    pub fn enable_fifo(&self, enable: bool) {
990        if enable {
991            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
992        } else {
993            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
994        }
995    }
996
997    /// 设置 FIFO 触发级别
998    pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
999        // PL011 FIFO 触发级别:
1000        // 0b000: 1/8 full
1001        // 0b001: 1/4 full
1002        // 0b010: 1/2 full
1003        // 0b011: 3/4 full
1004        // 0b100: 7/8 full
1005
1006        let rx_iflsel = match rx_level {
1007            0..=2 => 0b000,  // 1/8
1008            3..=4 => 0b001,  // 1/4
1009            5..=8 => 0b010,  // 1/2
1010            9..=12 => 0b011, // 3/4
1011            _ => 0b100,      // 7/8
1012        };
1013
1014        let tx_iflsel = match tx_level {
1015            0..=2 => 0b000,  // 1/8
1016            3..=4 => 0b001,  // 1/4
1017            5..=8 => 0b010,  // 1/2
1018            9..=12 => 0b011, // 3/4
1019            _ => 0b100,      // 7/8
1020        };
1021
1022        self.registers()
1023            .uartifls
1024            .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
1025    }
1026}
1027
1028// ModemStatus 现在在 lib.rs 中定义,这里只是导出
1029
1030#[cfg(test)]
1031mod tests {
1032    use core::ptr::NonNull;
1033    use std::{boxed::Box, vec::Vec};
1034
1035    use rdif_serial::UartRegisterGate;
1036
1037    use super::*;
1038
1039    // This adapter keeps the regression runnable against both the old `()`
1040    // API and the new `Result` API, so the same test exposes the old hang.
1041    trait AssertOpenTimeout {
1042        fn assert_timeout(self);
1043    }
1044
1045    impl AssertOpenTimeout for () {
1046        fn assert_timeout(self) {
1047            panic!("unbounded PL011 open returned without reporting a timeout");
1048        }
1049    }
1050
1051    impl AssertOpenTimeout for Result<(), ConfigError> {
1052        fn assert_timeout(self) {
1053            assert_eq!(self, Err(ConfigError::Timeout));
1054        }
1055    }
1056
1057    fn handle_irq(irq: &mut impl UartIrq) -> (Option<SerialIrqEvent>, Vec<RxSample>) {
1058        let Some(report) = irq.handle() else {
1059            return (None, Vec::new());
1060        };
1061        (Some(report.event), report.rx.as_slice().to_vec())
1062    }
1063
1064    fn pl011_with_registers() -> (Box<Pl011Registers>, Pl011) {
1065        let mut regs = Box::new(unsafe { core::mem::zeroed::<Pl011Registers>() });
1066        let ptr = NonNull::from(regs.as_mut()).cast::<u8>();
1067        let uart = Pl011::new(ptr, 24_000_000);
1068        (regs, uart)
1069    }
1070
1071    fn pl011_with_overrun_data() -> (Box<Pl011Registers>, Pl011) {
1072        let (regs, uart) = pl011_with_registers();
1073        regs.uartdr
1074            .set((UARTDR::DATA.val(0xab) + UARTDR::OE::SET).into());
1075        (regs, uart)
1076    }
1077
1078    fn write_test_reg(regs: &mut Pl011Registers, offset: usize, value: u32) {
1079        unsafe {
1080            (regs as *mut Pl011Registers)
1081                .cast::<u32>()
1082                .add(offset / core::mem::size_of::<u32>())
1083                .write_volatile(value);
1084        }
1085    }
1086
1087    fn read_test_reg(regs: &Pl011Registers, offset: usize) -> u32 {
1088        unsafe {
1089            (regs as *const Pl011Registers)
1090                .cast::<u32>()
1091                .add(offset / core::mem::size_of::<u32>())
1092                .read_volatile()
1093        }
1094    }
1095
1096    const CONFIG_REGISTER_OFFSETS: [usize; 8] =
1097        [0x020, 0x024, 0x028, 0x02c, 0x030, 0x034, 0x038, 0x048];
1098
1099    fn config_register_snapshot(regs: &Pl011Registers) -> [u32; 8] {
1100        CONFIG_REGISTER_OFFSETS.map(|offset| read_test_reg(regs, offset))
1101    }
1102
1103    fn seed_config_registers(regs: &mut Pl011Registers) {
1104        for (index, offset) in CONFIG_REGISTER_OFFSETS.into_iter().enumerate() {
1105            write_test_reg(regs, offset, 0x10 + index as u32);
1106        }
1107    }
1108
1109    fn started_parts(uart: Pl011) -> SerialParts<Pl011, Pl011Irq, Pl011EmergencyTx> {
1110        let mut parts = uart.split();
1111        parts.control.startup(&Config::new()).unwrap();
1112        parts
1113    }
1114
1115    #[test]
1116    fn early_console_open_has_a_bounded_busy_failure() {
1117        let (mut regs, mut uart) = pl011_with_registers();
1118        let original_uartcr = (UARTCR::UARTEN::SET
1119            + UARTCR::SIREN::SET
1120            + UARTCR::LBE::SET
1121            + UARTCR::TXE::SET
1122            + UARTCR::DTR::SET
1123            + UARTCR::OUT2::SET
1124            + UARTCR::CTSEN::SET)
1125            .value;
1126        write_test_reg(&mut regs, 0x018, UARTFR::BUSY::SET.value);
1127        write_test_reg(&mut regs, 0x030, original_uartcr);
1128
1129        uart.open().assert_timeout();
1130
1131        assert_eq!(read_test_reg(&regs, 0x030), original_uartcr);
1132    }
1133
1134    #[test]
1135    fn raw_rx_reports_overrun_instead_of_swallowing_it() {
1136        let (_regs, mut uart) = pl011_with_overrun_data();
1137
1138        let mut buf = [0];
1139        let err = uart
1140            .try_read(&mut buf)
1141            .expect_err("overrun must be reported to the caller");
1142
1143        assert_eq!(buf[0], 0xab);
1144        assert_eq!(err.bytes_transferred, 1);
1145        assert_eq!(err.kind, TransferError::Overrun(0xab));
1146    }
1147
1148    #[test]
1149    fn raw_rx_sample_reports_overrun_instead_of_swallowing_it() {
1150        let (mut regs, uart) = pl011_with_overrun_data();
1151        let mut parts = uart.split();
1152
1153        write_test_reg(&mut regs, 0x040, UARTIS::OE::SET.value);
1154        let (event, samples) = handle_irq(&mut parts.irq);
1155        let event = event.unwrap();
1156        assert!(event.events.contains(SerialEventSet::RX_STATUS));
1157        assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1158        assert_eq!(
1159            samples.len(),
1160            IRQ_RX_BATCH_CAPACITY,
1161            "the hard IRQ must enforce its RX budget"
1162        );
1163        let sample = samples[0];
1164        assert_eq!(sample.byte, Some(0xab));
1165        assert_eq!(sample.flag, RxFlag::Normal);
1166        assert!(sample.overrun);
1167    }
1168
1169    #[test]
1170    fn rx_irq_masks_source_after_bounded_fifo_drain() {
1171        let (mut regs, uart) = pl011_with_registers();
1172        let mut irq = uart.split().irq;
1173        let rx_mask = imsc_for_events(SerialEventSet::RX);
1174        write_test_reg(&mut regs, 0x038, rx_mask);
1175        write_test_reg(&mut regs, 0x040, UARTIS::RX::SET.value);
1176        write_test_reg(&mut regs, 0x018, 0);
1177        regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1178
1179        let (event, samples) = handle_irq(&mut irq);
1180        let event = event.unwrap();
1181
1182        assert!(event.events.contains(SerialEventSet::RX_DATA));
1183        assert!(event.rearm.contains(SerialEventSet::RX));
1184        assert_eq!(samples.len(), IRQ_RX_BATCH_CAPACITY);
1185        assert_eq!(read_test_reg(&regs, 0x038) & rx_mask, 0);
1186    }
1187
1188    #[test]
1189    fn irq_status_without_rx_byte_is_preserved_after_irq_ack() {
1190        let (mut regs, uart) = pl011_with_registers();
1191        let mut parts = uart.split();
1192
1193        write_test_reg(
1194            &mut regs,
1195            0x040,
1196            UARTIS::OE::SET.value | UARTIS::PE::SET.value,
1197        );
1198        write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1199
1200        let event = handle_irq(&mut parts.irq).0.unwrap();
1201        assert!(event.events.contains(SerialEventSet::RX_STATUS));
1202        assert!(event.rx_errors.contains(RxErrorFlags::PARITY));
1203        assert!(event.rx_errors.contains(RxErrorFlags::OVERRUN));
1204        assert!(parts.control.read_rx().is_none());
1205    }
1206
1207    #[test]
1208    fn tx_irq_exposes_space_without_owning_a_software_fifo() {
1209        let (mut regs, uart) = pl011_with_registers();
1210        let mut parts = started_parts(uart);
1211
1212        write_test_reg(&mut regs, 0x018, 0);
1213        write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1214        let event = handle_irq(&mut parts.irq).0.unwrap();
1215        assert!(event.events.contains(SerialEventSet::TX_SPACE));
1216        assert_eq!(parts.control.write_tx(b"x"), 1);
1217        assert_eq!(regs.uartdr.get() as u8, b'x');
1218    }
1219
1220    #[test]
1221    fn emergency_tx_returns_immediately_when_the_fifo_is_full() {
1222        let (mut regs, uart) = pl011_with_registers();
1223        let parts = uart.split();
1224        let gate = UartRegisterGate::new(parts.emergency_tx);
1225        let access = gate.try_begin_emergency().unwrap();
1226        write_test_reg(&mut regs, 0x018, UARTFR::TXFF::SET.value);
1227
1228        assert_eq!(access.try_write(b"x"), 0);
1229
1230        write_test_reg(&mut regs, 0x018, 0);
1231        assert_eq!(access.try_write(b"x"), 1);
1232        assert_eq!(regs.uartdr.get() as u8, b'x');
1233    }
1234
1235    #[test]
1236    fn emergency_tx_has_a_fixed_write_budget() {
1237        let (mut regs, uart) = pl011_with_registers();
1238        let parts = uart.split();
1239        write_test_reg(&mut regs, 0x018, 0);
1240        let bytes = [b'x'; EMERGENCY_TX_BUDGET + 1];
1241        let gate = UartRegisterGate::new(parts.emergency_tx);
1242        let access = gate.try_begin_emergency().unwrap();
1243
1244        assert_eq!(access.try_write(&bytes), EMERGENCY_TX_BUDGET);
1245    }
1246
1247    #[test]
1248    fn emergency_takeover_leaves_device_interrupts_masked() {
1249        let (mut regs, uart) = pl011_with_registers();
1250        let gate = UartRegisterGate::new(uart.split().emergency_tx);
1251        let enabled = UARTIS::RX::SET.value | UARTIS::TX::SET.value;
1252        write_test_reg(&mut regs, 0x038, enabled);
1253
1254        let access = gate.try_begin_emergency().unwrap();
1255        assert_eq!(
1256            read_test_reg(&regs, 0x038),
1257            0,
1258            "a gate-busy IRQ must observe a device-masked emergency transaction"
1259        );
1260        assert_eq!(access.try_write(b"x"), 1);
1261        assert_eq!(
1262            read_test_reg(&regs, 0x038),
1263            0,
1264            "terminal emergency ownership must not rearm the UART source"
1265        );
1266    }
1267
1268    #[test]
1269    fn discard_rx_clears_saved_status_without_touching_tx_data() {
1270        let (mut regs, mut uart) = pl011_with_registers();
1271        uart.saved_rx_status = Pl011RxStatus::PARITY;
1272        regs.uartdr.set(UARTDR::DATA.val(b'x' as u32).into());
1273        write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1274
1275        UartPort::discard_rx(&mut uart);
1276
1277        assert!(uart.saved_rx_status.is_empty());
1278        assert_eq!(regs.uartdr.get() as u8, b'x');
1279        assert_eq!(
1280            read_test_reg(&regs, 0x044) & imsc_for_events(SerialEventSet::RX),
1281            imsc_for_events(SerialEventSet::RX),
1282        );
1283    }
1284
1285    #[test]
1286    fn discard_tx_reports_unsupported_without_touching_rx_data() {
1287        let (mut regs, mut uart) = pl011_with_registers();
1288        regs.uartlcr_h.modify(UARTLCR_H::FEN::SET);
1289        regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1290        write_test_reg(&mut regs, 0x018, 0);
1291        let lcr_h = regs.uartlcr_h.get();
1292
1293        assert!(!UartPort::discard_tx(&mut uart));
1294        assert_eq!(regs.uartlcr_h.get(), lcr_h);
1295        assert_eq!(uart.read_rx().unwrap().byte, Some(b'r'));
1296    }
1297
1298    #[test]
1299    fn tx_irq_endpoint_acknowledges_tx_interrupt() {
1300        let (mut regs, uart) = pl011_with_registers();
1301        let mut irq = uart.split().irq;
1302
1303        write_test_reg(&mut regs, 0x000, 0x5a);
1304        write_test_reg(&mut regs, 0x038, UARTIS::TX::SET.value);
1305        write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
1306        let event = handle_irq(&mut irq).0.unwrap();
1307
1308        assert!(event.events.contains(SerialEventSet::TX_SPACE));
1309        assert_eq!(event.rearm, SerialEventSet::TX_SPACE);
1310        assert_eq!(
1311            read_test_reg(&regs, 0x044) & UARTIS::TX::SET.value,
1312            UARTIS::TX::SET.value
1313        );
1314        assert_eq!(read_test_reg(&regs, 0x038) & UARTIS::TX::SET.value, 0);
1315        assert_eq!(read_test_reg(&regs, 0x000), 0x5a);
1316    }
1317
1318    #[test]
1319    fn overrun_irq_masks_receive_sources_until_worker_rearm() {
1320        let (mut regs, uart) = pl011_with_registers();
1321        let mut irq = uart.split().irq;
1322        let rx_sources = imsc_for_events(SerialEventSet::RX);
1323        write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1324        write_test_reg(&mut regs, 0x038, rx_sources);
1325        write_test_reg(&mut regs, 0x040, UARTIS::OE::SET.value);
1326
1327        let report = irq.handle().expect("PL011 overrun interrupt report");
1328
1329        assert!(report.event.rx_errors.contains(RxErrorFlags::OVERRUN));
1330        assert!(report.event.rearm.contains(SerialEventSet::RX));
1331        assert_eq!(read_test_reg(&regs, 0x038) & rx_sources, 0);
1332    }
1333
1334    #[test]
1335    fn drained_rx_irq_keeps_receive_sources_enabled() {
1336        let (mut regs, uart) = pl011_with_registers();
1337        let mut irq = uart.split().irq;
1338        let rx_sources = imsc_for_events(SerialEventSet::RX);
1339        write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
1340        write_test_reg(&mut regs, 0x038, rx_sources);
1341        write_test_reg(&mut regs, 0x040, UARTIS::RX::SET.value);
1342
1343        let report = irq.handle().expect("PL011 drained RX interrupt report");
1344
1345        assert!(report.rx.is_empty());
1346        assert!(!report.event.rearm.intersects(SerialEventSet::RX));
1347        assert_eq!(read_test_reg(&regs, 0x038) & rx_sources, rx_sources);
1348    }
1349
1350    #[test]
1351    fn set_config_preserves_enabled_tx_and_rx_paths() {
1352        let (regs, mut uart) = pl011_with_registers();
1353        regs.uartcr
1354            .write(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
1355
1356        uart.set_config(&Config::new()).unwrap();
1357
1358        let cr = regs.uartcr.extract();
1359        assert!(cr.is_set(UARTCR::UARTEN));
1360        assert!(cr.is_set(UARTCR::TXE));
1361        assert!(cr.is_set(UARTCR::RXE));
1362    }
1363
1364    #[test]
1365    fn set_config_busy_timeout_restores_every_configuration_register() {
1366        let (mut regs, mut uart) = pl011_with_registers();
1367        seed_config_registers(&mut regs);
1368        let before = config_register_snapshot(&regs);
1369        write_test_reg(&mut regs, 0x018, UARTFR::BUSY::SET.value);
1370
1371        let result = uart.set_config(&Config::new().baudrate(115_200));
1372
1373        assert_eq!(result, Err(ConfigError::Timeout));
1374        assert_eq!(config_register_snapshot(&regs), before);
1375    }
1376
1377    #[test]
1378    fn invalid_config_restores_every_configuration_register() {
1379        let (mut regs, mut uart) = pl011_with_registers();
1380        seed_config_registers(&mut regs);
1381        write_test_reg(&mut regs, 0x018, 0);
1382        let before = config_register_snapshot(&regs);
1383
1384        let result = uart.set_config(&Config::new().baudrate(2_000_000));
1385
1386        assert_eq!(result, Err(ConfigError::InvalidBaudrate));
1387        assert_eq!(config_register_snapshot(&regs), before);
1388    }
1389
1390    #[test]
1391    fn rx_available_mask_enables_timeout_and_error_interrupts() {
1392        let (regs, mut uart) = pl011_with_registers();
1393
1394        uart.set_irq_mask(SerialEventSet::RX);
1395
1396        let imsc = regs.uartimsc.extract();
1397        assert!(imsc.is_set(UARTIS::RX));
1398        assert!(imsc.is_set(UARTIS::RT));
1399        assert!(imsc.is_set(UARTIS::FE));
1400        assert!(imsc.is_set(UARTIS::PE));
1401        assert!(imsc.is_set(UARTIS::BE));
1402        assert!(imsc.is_set(UARTIS::OE));
1403        assert_eq!(uart.get_irq_mask(), SerialEventSet::RX);
1404    }
1405
1406    #[test]
1407    fn hard_irq_does_not_claim_rx_ready_without_mis() {
1408        let (mut regs, uart) = pl011_with_registers();
1409        let mut parts = uart.split();
1410
1411        parts.control.set_irq_mask(SerialEventSet::RX);
1412        write_test_reg(&mut regs, 0x040, 0);
1413        write_test_reg(&mut regs, 0x018, 0);
1414
1415        assert!(handle_irq(&mut parts.irq).0.is_none());
1416    }
1417
1418    #[test]
1419    fn port_rx_ready_is_visible_without_irq_event() {
1420        let (mut regs, mut uart) = pl011_with_registers();
1421
1422        uart.set_irq_mask(SerialEventSet::RX);
1423        write_test_reg(&mut regs, 0x040, 0);
1424        write_test_reg(&mut regs, 0x018, 0);
1425        regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1426
1427        let status = uart.poll_status();
1428        assert!(status.rx_ready());
1429        let sample = uart.read_rx().expect("RX sample should be available");
1430        assert_eq!(sample.byte, Some(b'r'));
1431        assert_eq!(sample.flag, RxFlag::Normal);
1432    }
1433
1434    #[test]
1435    fn rearm_remasks_rx_when_fifo_is_already_ready() {
1436        let (mut regs, mut uart) = pl011_with_registers();
1437        write_test_reg(&mut regs, 0x018, 0);
1438
1439        let ready = uart.rearm(SerialEventSet::RX);
1440
1441        assert_eq!(ready, SerialEventSet::RX_DATA);
1442        assert_eq!(
1443            read_test_reg(&regs, 0x038) & imsc_for_events(SerialEventSet::RX),
1444            0
1445        );
1446    }
1447
1448    #[test]
1449    fn unknown_irq_source_masks_all_without_fifo_access() {
1450        let (mut regs, uart) = pl011_with_registers();
1451        let mut irq = uart.split().irq;
1452        write_test_reg(&mut regs, 0x000, 0x5a);
1453        write_test_reg(&mut regs, 0x038, u32::MAX);
1454        write_test_reg(&mut regs, 0x040, 1 << 31);
1455
1456        let event = handle_irq(&mut irq).0.unwrap();
1457
1458        assert!(event.events.contains(SerialEventSet::FAULT));
1459        assert_eq!(read_test_reg(&regs, 0x038), 0);
1460        assert_eq!(read_test_reg(&regs, 0x000), 0x5a);
1461    }
1462}