Skip to main content

some_serial/
pl011.rs

1use core::{num::NonZeroU32, ptr::NonNull};
2
3use rdif_serial::{
4    InterruptMask, IrqSnapshot, IrqSource, RawUart, RxFlag, RxSample, SerialDirection, SerialEvent,
5    TransBytesError, TransferError,
6};
7use tock_registers::{
8    LocalRegisterCopy, interfaces::*, register_bitfields, register_structs, registers::*,
9};
10
11use crate::{Config, ConfigError, DataBits, Parity, StopBits};
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    /// 自动检测或确定合理的时钟频率
176    fn detect_clock_frequency(base: usize) -> u32 {
177        // 尝试读取当前波特率设置来反向推算时钟频率
178        let registers = unsafe { &*(base as *const Pl011Registers) };
179
180        use tock_registers::interfaces::Readable;
181        let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
182
183        // 如果有设置值,假设波特率为 115200 来估算时钟频率
184        if ibrd > 0 && ibrd <= 0xFFFF {
185            // 假设波特率为 115200,计算时钟频率
186            // FUARTCLK = 16 * BAUDDIV * Baud rate
187            let estimated_clock = 16 * ibrd * 115200;
188
189            // 合理的时钟频率范围:1MHz - 100MHz
190            if (1_000_000..=100_000_000).contains(&estimated_clock) {
191                return estimated_clock;
192            }
193        }
194
195        // 默认使用 24MHz(最常见)
196        24_000_000
197    }
198
199    // 内部私有方法,用于配置
200    fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
201        // PL011 波特率计算公式:
202        // BAUDDIV = (FUARTCLK / (16 * Baud rate))
203        // IBRD = integer(BAUDDIV)
204        // FBRD = integer((BAUDDIV - IBRD) * 64 + 0.5)
205
206        let bauddiv = self.clock_freq / (16 * baudrate);
207        let remainder = self.clock_freq % (16 * baudrate);
208        let fbrd = (remainder * 64 + (16 * baudrate / 2)) / (16 * baudrate);
209
210        if bauddiv == 0 || bauddiv > 0xFFFF {
211            return Err(ConfigError::InvalidBaudrate);
212        }
213
214        self.registers()
215            .uartibrd
216            .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
217        self.registers()
218            .uartfbrd
219            .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
220
221        Ok(())
222    }
223
224    fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
225        let wlen = match bits {
226            DataBits::Five => UARTLCR_H::WLEN::FiveBit,
227            DataBits::Six => UARTLCR_H::WLEN::SixBit,
228            DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
229            DataBits::Eight => UARTLCR_H::WLEN::EightBit,
230        };
231
232        self.registers().uartlcr_h.modify(wlen);
233        Ok(())
234    }
235
236    fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
237        match bits {
238            StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
239            StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
240        }
241
242        Ok(())
243    }
244
245    fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
246        match parity {
247            Parity::None => {
248                // PEN = 0, 无奇偶校验
249                self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
250            }
251            Parity::Odd => {
252                // PEN = 1, EPS = 0 (奇校验), SPS = 0
253                self.registers()
254                    .uartlcr_h
255                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
256            }
257            Parity::Even => {
258                // PEN = 1, EPS = 1 (偶校验), SPS = 0
259                self.registers()
260                    .uartlcr_h
261                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
262            }
263            Parity::Mark => {
264                // PEN = 1, SPS = 1, EPS = 0 (奇校验)
265                self.registers()
266                    .uartlcr_h
267                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
268            }
269            Parity::Space => {
270                // PEN = 1, EPS = 1 (偶校验), SPS = 1
271                self.registers()
272                    .uartlcr_h
273                    .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
274            }
275        }
276
277        Ok(())
278    }
279
280    /// 初始化 PL011 UART
281    pub fn open(&mut self) {
282        // 禁用 UART
283        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
284
285        // 等待当前传输完成
286        while self.registers().uartfr.is_set(UARTFR::BUSY) {
287            core::hint::spin_loop();
288        }
289
290        // 清除发送 FIFO
291        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
292
293        // 启用 FIFO
294        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
295
296        // 调试信息:输出 FIFO 配置
297        #[cfg(debug_assertions)]
298        {
299            let ifls = self.registers().uartifls.get();
300            let lcr_h = self.registers().uartlcr_h.get();
301            log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
302            log::debug!("  FIFO enabled: {}", lcr_h & (1 << 4) != 0);
303            log::debug!("  RX trigger level: 1/8");
304            log::debug!("  TX trigger level: 1/2");
305        }
306        self.registers().uartimsc.set(0); // 禁用所有中断
307        // 启用 UART
308        self.registers()
309            .uartcr
310            .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
311    }
312
313    pub fn set_irq_mask(&mut self, mask: InterruptMask) {
314        let mut imsc = 0;
315        if mask.intersects(InterruptMask::RX) {
316            imsc |= UARTIS::RX::SET.value
317                | UARTIS::RT::SET.value
318                | UARTIS::FE::SET.value
319                | UARTIS::PE::SET.value
320                | UARTIS::BE::SET.value
321                | UARTIS::OE::SET.value;
322        }
323        if mask.contains(InterruptMask::TX_SPACE) {
324            imsc |= UARTIS::TX::SET.value;
325        }
326
327        self.registers().uartimsc.set(imsc);
328    }
329
330    pub fn get_irq_mask(&self) -> InterruptMask {
331        let imsc = self.registers().uartimsc.extract();
332        let mut mask = InterruptMask::empty();
333
334        if imsc.is_set(UARTIS::RX)
335            || imsc.is_set(UARTIS::RT)
336            || imsc.is_set(UARTIS::FE)
337            || imsc.is_set(UARTIS::PE)
338            || imsc.is_set(UARTIS::BE)
339            || imsc.is_set(UARTIS::OE)
340        {
341            mask |= InterruptMask::RX;
342        }
343        if imsc.is_set(UARTIS::TX) {
344            mask |= InterruptMask::TX_SPACE;
345        }
346
347        mask
348    }
349
350    pub fn pending(&mut self, direction: SerialDirection) -> bool {
351        match direction {
352            SerialDirection::Input => !self.registers().uartfr.is_set(UARTFR::RXFE),
353            SerialDirection::Output => !self.registers().uartfr.is_set(UARTFR::TXFF),
354        }
355    }
356
357    pub fn poll_status(&mut self) -> SerialEvent {
358        let mut event = SerialEvent::empty();
359        let fr = self.registers().uartfr.extract();
360        if !fr.is_set(UARTFR::RXFE) {
361            event |= SerialEvent::RX_READY;
362        }
363        if !fr.is_set(UARTFR::TXFF) {
364            event |= SerialEvent::TX_READY;
365        }
366
367        let status =
368            self.saved_rx_status | Pl011RxStatus::from_rsr(self.registers().uartrsr_ecr.extract());
369        if status.intersects(Pl011RxStatus::FRAMING | Pl011RxStatus::PARITY | Pl011RxStatus::BREAK)
370        {
371            event |= SerialEvent::RX_ERROR;
372        }
373        if status.contains(Pl011RxStatus::OVERRUN) {
374            event |= SerialEvent::RX_ERROR | SerialEvent::OVERRUN;
375        }
376
377        event
378    }
379
380    pub fn try_write(&mut self, bytes: &[u8]) -> usize {
381        let mut written = 0;
382        for &byte in bytes {
383            let status = self.poll_status();
384            if !status.tx_ready() {
385                break;
386            }
387            self.write_byte(byte);
388            written += 1;
389        }
390        written
391    }
392
393    pub fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
394        let mut count = 0;
395        for byte in bytes.iter_mut() {
396            let status = self.poll_status();
397            if !status.rx_ready() && !status.rx_error() {
398                break;
399            }
400            match self.read_byte(status) {
401                Some(Ok(b)) => {
402                    *byte = b;
403                }
404                Some(Err(TransferError::Overrun(b))) => {
405                    *byte = b;
406                    count += 1;
407                    return Err(TransBytesError {
408                        bytes_transferred: count,
409                        kind: TransferError::Overrun(b),
410                    });
411                }
412                Some(Err(e)) => {
413                    return Err(TransBytesError {
414                        bytes_transferred: count,
415                        kind: e,
416                    });
417                }
418                None => break,
419            }
420            count += 1;
421        }
422        Ok(count)
423    }
424
425    pub fn handle_irq(&mut self) -> SerialEvent {
426        serial_event_from_snapshot(self.take_irq_snapshot())
427    }
428
429    pub fn write_byte(&mut self, byte: u8) {
430        self.registers().uartdr.set(byte as _);
431    }
432
433    pub fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
434        if !status.rx_ready() && !status.rx_error() {
435            return None;
436        }
437
438        let sample = self.read_rx()?;
439        if sample.overrun {
440            return Some(Err(TransferError::Overrun(sample.byte.unwrap_or(0))));
441        }
442        match sample.flag {
443            RxFlag::Normal => sample.byte.map(Ok),
444            RxFlag::Break => Some(Err(TransferError::Break)),
445            RxFlag::Parity => Some(Err(TransferError::Parity)),
446            RxFlag::Framing => Some(Err(TransferError::Framing)),
447        }
448    }
449
450    pub fn take_irq_snapshot(&mut self) -> IrqSnapshot {
451        let mis = self.registers().uartmis.extract();
452        let active = mis.get();
453        if active == 0 {
454            return IrqSnapshot::default();
455        }
456
457        let mut sources = IrqSource::empty();
458        if mis.is_set(UARTIS::RX) {
459            sources |= IrqSource::RX_DATA;
460        }
461        if mis.is_set(UARTIS::RT) {
462            sources |= IrqSource::RX_TIMEOUT;
463        }
464        if mis.is_set(UARTIS::FE)
465            || mis.is_set(UARTIS::PE)
466            || mis.is_set(UARTIS::BE)
467            || mis.is_set(UARTIS::OE)
468        {
469            sources |= IrqSource::RX_STATUS;
470            self.saved_rx_status |= Pl011RxStatus::from_irq_status(mis);
471        }
472        if mis.is_set(UARTIS::TX) {
473            sources |= IrqSource::TX_SPACE;
474        }
475        if mis.is_set(UARTIS::CTSM)
476            || mis.is_set(UARTIS::DSRM)
477            || mis.is_set(UARTIS::DCDM)
478            || mis.is_set(UARTIS::RIM)
479        {
480            sources |= IrqSource::MODEM_STATUS;
481        }
482
483        self.registers()
484            .uarticr
485            .set(active & !(UARTIS::RX::SET.value | UARTIS::RT::SET.value));
486
487        IrqSnapshot {
488            claimed: true,
489            sources,
490        }
491    }
492
493    pub fn read_rx(&mut self) -> Option<RxSample> {
494        if self.registers().uartfr.is_set(UARTFR::RXFE) {
495            self.saved_rx_status |= Pl011RxStatus::from_rsr(self.registers().uartrsr_ecr.extract());
496            return self.saved_rx_status.take_status_sample();
497        }
498
499        let dr = self.registers().uartdr.extract();
500        let data = dr.read(UARTDR::DATA) as u8;
501        let status = Pl011RxStatus::from_data(dr);
502        if !status.is_empty() {
503            self.saved_rx_status.remove(status);
504        }
505
506        let flag = if status.contains(Pl011RxStatus::BREAK) {
507            RxFlag::Break
508        } else if status.contains(Pl011RxStatus::PARITY) {
509            RxFlag::Parity
510        } else if status.contains(Pl011RxStatus::FRAMING) {
511            RxFlag::Framing
512        } else {
513            RxFlag::Normal
514        };
515
516        Some(RxSample {
517            byte: Some(data),
518            flag,
519            overrun: status.contains(Pl011RxStatus::OVERRUN),
520        })
521    }
522}
523
524bitflags::bitflags! {
525    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
526    struct Pl011RxStatus: u32 {
527        const FRAMING = 1 << 0;
528        const PARITY  = 1 << 1;
529        const BREAK   = 1 << 2;
530        const OVERRUN = 1 << 3;
531    }
532}
533
534impl Pl011RxStatus {
535    fn from_data(dr: LocalRegisterCopy<u32, UARTDR::Register>) -> Self {
536        let mut status = Self::empty();
537        if dr.is_set(UARTDR::FE) {
538            status |= Self::FRAMING;
539        }
540        if dr.is_set(UARTDR::PE) {
541            status |= Self::PARITY;
542        }
543        if dr.is_set(UARTDR::BE) {
544            status |= Self::BREAK;
545        }
546        if dr.is_set(UARTDR::OE) {
547            status |= Self::OVERRUN;
548        }
549        status
550    }
551
552    fn from_irq_status(mis: LocalRegisterCopy<u32, UARTIS::Register>) -> Self {
553        let mut status = Self::empty();
554        if mis.is_set(UARTIS::FE) {
555            status |= Self::FRAMING;
556        }
557        if mis.is_set(UARTIS::PE) {
558            status |= Self::PARITY;
559        }
560        if mis.is_set(UARTIS::BE) {
561            status |= Self::BREAK;
562        }
563        if mis.is_set(UARTIS::OE) {
564            status |= Self::OVERRUN;
565        }
566        status
567    }
568
569    fn from_rsr(rsr: LocalRegisterCopy<u32, UARTRSR_ECR::Register>) -> Self {
570        let mut status = Self::empty();
571        if rsr.is_set(UARTRSR_ECR::FE) {
572            status |= Self::FRAMING;
573        }
574        if rsr.is_set(UARTRSR_ECR::PE) {
575            status |= Self::PARITY;
576        }
577        if rsr.is_set(UARTRSR_ECR::BE) {
578            status |= Self::BREAK;
579        }
580        if rsr.is_set(UARTRSR_ECR::OE) {
581            status |= Self::OVERRUN;
582        }
583        status
584    }
585
586    fn flag(self) -> RxFlag {
587        if self.contains(Self::BREAK) {
588            RxFlag::Break
589        } else if self.contains(Self::PARITY) {
590            RxFlag::Parity
591        } else if self.contains(Self::FRAMING) {
592            RxFlag::Framing
593        } else {
594            RxFlag::Normal
595        }
596    }
597
598    fn take_status_sample(&mut self) -> Option<RxSample> {
599        if self.is_empty() {
600            return None;
601        }
602
603        let status = *self;
604        *self = Self::empty();
605        Some(RxSample {
606            byte: None,
607            flag: status.flag(),
608            overrun: status.contains(Self::OVERRUN),
609        })
610    }
611}
612
613fn serial_event_from_snapshot(snapshot: IrqSnapshot) -> SerialEvent {
614    let mut event = SerialEvent::empty();
615    if !snapshot.claimed {
616        return event;
617    }
618    if snapshot
619        .sources
620        .intersects(IrqSource::RX_DATA | IrqSource::RX_TIMEOUT)
621    {
622        event |= SerialEvent::RX_READY;
623    }
624    if snapshot.sources.contains(IrqSource::RX_STATUS) {
625        event |= SerialEvent::RX_ERROR;
626    }
627    if snapshot.sources.contains(IrqSource::TX_SPACE) {
628        event |= SerialEvent::TX_READY;
629    }
630    if snapshot.sources.contains(IrqSource::MODEM_STATUS) {
631        event |= SerialEvent::MODEM_STATUS;
632    }
633    event
634}
635
636#[derive(Clone, Copy, PartialEq, Eq)]
637struct Reg(NonNull<Pl011Registers>);
638
639unsafe impl Send for Reg {}
640unsafe impl Sync for Reg {}
641
642impl RawUart for Pl011 {
643    fn name(&self) -> &'static str {
644        "PL011 UART"
645    }
646
647    fn base_addr(&self) -> usize {
648        self.base.0.as_ptr() as usize
649    }
650
651    fn clock_freq(&self) -> Option<NonZeroU32> {
652        self.clock_freq.try_into().ok()
653    }
654
655    fn startup(&mut self, config: &Config) -> Result<(), ConfigError> {
656        self.open();
657        self.set_config(config)?;
658        self.set_irq_mask(InterruptMask::empty());
659        Ok(())
660    }
661
662    fn shutdown(&mut self) {
663        self.registers().uartimsc.set(0);
664        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
665    }
666
667    fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
668        use tock_registers::interfaces::Readable;
669
670        // 根据ARM文档的建议配置流程:
671        // 1. 禁用UART
672        let original_cr = self.registers().uartcr.extract(); // 保存原始使能状态
673        self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR); // 禁用UART
674
675        // 2. 等待当前字符传输完成
676        while self.registers().uartfr.is_set(UARTFR::BUSY) {
677            core::hint::spin_loop();
678        }
679
680        // 3. 刷新发送FIFO(通过设置FEN=0)
681        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
682
683        // 4. 配置各项参数
684        if let Some(baudrate) = config.baudrate {
685            self.set_baudrate_internal(baudrate)?;
686        }
687        if let Some(data_bits) = config.data_bits {
688            self.set_data_bits_internal(data_bits)?;
689        }
690        if let Some(stop_bits) = config.stop_bits {
691            self.set_stop_bits_internal(stop_bits)?;
692        }
693        if let Some(parity) = config.parity {
694            self.set_parity_internal(parity)?;
695        }
696
697        // 5. 重新启用FIFO
698        self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
699
700        // 6. 恢复UART使能状态
701        if original_cr.is_set(UARTCR::UARTEN) {
702            self.registers().uartcr.modify(
703                UARTCR::UARTEN.val(original_cr.read(UARTCR::UARTEN))
704                    + UARTCR::TXE.val(original_cr.read(UARTCR::TXE))
705                    + UARTCR::RXE.val(original_cr.read(UARTCR::RXE)),
706            );
707        }
708
709        Ok(())
710    }
711
712    fn baudrate(&self) -> u32 {
713        let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
714        let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
715
716        // 反向计算波特率
717        // Baud rate = FUARTCLK / (16 * (IBRD + FBRD/64))
718        let divisor = ibrd * 64 + fbrd;
719        if divisor == 0 {
720            return 0;
721        }
722
723        self.clock_freq * 64 / (16 * divisor)
724    }
725
726    fn data_bits(&self) -> DataBits {
727        let wlen = self.registers().uartlcr_h.read(UARTLCR_H::WLEN);
728
729        match wlen {
730            0 => DataBits::Five,
731            1 => DataBits::Six,
732            2 => DataBits::Seven,
733            3 => DataBits::Eight,
734            _ => DataBits::Eight, // 默认值
735        }
736    }
737
738    fn stop_bits(&self) -> StopBits {
739        if self.registers().uartlcr_h.is_set(UARTLCR_H::STP2) {
740            StopBits::Two
741        } else {
742            StopBits::One
743        }
744    }
745
746    fn parity(&self) -> Parity {
747        if !self.registers().uartlcr_h.is_set(UARTLCR_H::PEN) {
748            Parity::None
749        } else if self.registers().uartlcr_h.is_set(UARTLCR_H::SPS) {
750            // Stick parity
751            if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
752                Parity::Space
753            } else {
754                Parity::Mark
755            }
756        } else {
757            // Normal parity
758            if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
759                Parity::Even
760            } else {
761                Parity::Odd
762            }
763        }
764    }
765
766    fn enable_loopback(&mut self) {
767        self.registers().uartcr.modify(UARTCR::LBE::SET);
768    }
769
770    fn disable_loopback(&mut self) {
771        self.registers().uartcr.modify(UARTCR::LBE::CLEAR);
772    }
773
774    fn is_loopback_enabled(&self) -> bool {
775        self.registers().uartcr.is_set(UARTCR::LBE)
776    }
777
778    fn set_irq_mask(&mut self, mask: InterruptMask) {
779        Pl011::set_irq_mask(self, mask);
780    }
781
782    fn take_irq_snapshot(&mut self) -> IrqSnapshot {
783        Pl011::take_irq_snapshot(self)
784    }
785
786    fn read_rx(&mut self) -> Option<RxSample> {
787        Pl011::read_rx(self)
788    }
789
790    fn tx_ready(&mut self) -> bool {
791        !self.registers().uartfr.is_set(UARTFR::TXFF)
792    }
793
794    fn write_tx(&mut self, byte: u8) {
795        Pl011::write_byte(self, byte);
796    }
797
798    fn tx_load_size(&self) -> usize {
799        16
800    }
801
802    fn tx_idle(&mut self) -> bool {
803        let fr = self.registers().uartfr.extract();
804        !fr.is_set(UARTFR::BUSY) && !fr.is_set(UARTFR::TXFF)
805    }
806
807    fn poll_status(&mut self) -> SerialEvent {
808        Pl011::poll_status(self)
809    }
810
811    fn write_byte(&mut self, byte: u8) {
812        Pl011::write_byte(self, byte)
813    }
814
815    fn read_byte(&mut self, status: SerialEvent) -> Option<Result<u8, TransferError>> {
816        Pl011::read_byte(self, status)
817    }
818}
819
820// 额外的便利方法,用于 FIFO 和流控制
821impl Pl011 {
822    /// 启用或禁用 FIFO
823    pub fn enable_fifo(&self, enable: bool) {
824        if enable {
825            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
826        } else {
827            self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
828        }
829    }
830
831    /// 设置 FIFO 触发级别
832    pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
833        // PL011 FIFO 触发级别:
834        // 0b000: 1/8 full
835        // 0b001: 1/4 full
836        // 0b010: 1/2 full
837        // 0b011: 3/4 full
838        // 0b100: 7/8 full
839
840        let rx_iflsel = match rx_level {
841            0..=2 => 0b000,  // 1/8
842            3..=4 => 0b001,  // 1/4
843            5..=8 => 0b010,  // 1/2
844            9..=12 => 0b011, // 3/4
845            _ => 0b100,      // 7/8
846        };
847
848        let tx_iflsel = match tx_level {
849            0..=2 => 0b000,  // 1/8
850            3..=4 => 0b001,  // 1/4
851            5..=8 => 0b010,  // 1/2
852            9..=12 => 0b011, // 3/4
853            _ => 0b100,      // 7/8
854        };
855
856        self.registers()
857            .uartifls
858            .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
859    }
860}
861
862// ModemStatus 现在在 lib.rs 中定义,这里只是导出
863
864#[cfg(test)]
865mod tests {
866    use core::ptr::NonNull;
867    use std::boxed::Box;
868
869    use rdif_serial::{OwnerId, OwnerLease, SerialParts, SerialPort};
870
871    use super::*;
872
873    fn pl011_with_registers() -> (Box<Pl011Registers>, Pl011) {
874        let mut regs = Box::new(unsafe { core::mem::zeroed::<Pl011Registers>() });
875        let ptr = NonNull::from(regs.as_mut()).cast::<u8>();
876        let uart = Pl011::new(ptr, 24_000_000);
877        (regs, uart)
878    }
879
880    fn pl011_with_overrun_data() -> (Box<Pl011Registers>, Pl011) {
881        let (regs, uart) = pl011_with_registers();
882        regs.uartdr
883            .set((UARTDR::DATA.val(0xab) + UARTDR::OE::SET).into());
884        (regs, uart)
885    }
886
887    fn write_test_reg(regs: &mut Pl011Registers, offset: usize, value: u32) {
888        unsafe {
889            (regs as *mut Pl011Registers)
890                .cast::<u32>()
891                .add(offset / core::mem::size_of::<u32>())
892                .write_volatile(value);
893        }
894    }
895
896    fn read_test_reg(regs: &Pl011Registers, offset: usize) -> u32 {
897        unsafe {
898            (regs as *const Pl011Registers)
899                .cast::<u32>()
900                .add(offset / core::mem::size_of::<u32>())
901                .read_volatile()
902        }
903    }
904
905    fn owner_lease() -> OwnerLease<'static> {
906        unsafe { OwnerLease::new_unchecked(OwnerId(0)) }
907    }
908
909    fn started_parts(uart: Pl011) -> SerialParts<64, 64> {
910        let parts = SerialPort::<64, 64>::split(uart, OwnerId(0));
911        parts.port.startup(owner_lease(), &Config::new()).unwrap();
912        parts
913    }
914
915    #[test]
916    fn raw_rx_reports_overrun_instead_of_swallowing_it() {
917        let (_regs, mut uart) = pl011_with_overrun_data();
918
919        let mut buf = [0];
920        let err = uart
921            .try_read(&mut buf)
922            .expect_err("overrun must be reported to the caller");
923
924        assert_eq!(buf[0], 0xab);
925        assert_eq!(err.bytes_transferred, 1);
926        assert_eq!(err.kind, TransferError::Overrun(0xab));
927    }
928
929    #[test]
930    fn raw_rx_sample_reports_overrun_instead_of_swallowing_it() {
931        let (mut regs, uart) = pl011_with_overrun_data();
932        let mut uart = uart;
933
934        write_test_reg(&mut regs, 0x040, UARTIS::OE::SET.value);
935        let snapshot = uart.take_irq_snapshot();
936        assert!(snapshot.claimed);
937        assert!(snapshot.sources.contains(IrqSource::RX_STATUS));
938
939        let sample = uart.read_rx().expect("RX sample should be available");
940        assert_eq!(sample.byte, Some(0xab));
941        assert_eq!(sample.flag, RxFlag::Normal);
942        assert!(sample.overrun);
943    }
944
945    #[test]
946    fn irq_status_without_rx_byte_is_preserved_after_irq_ack() {
947        let (mut regs, mut uart) = pl011_with_registers();
948
949        write_test_reg(
950            &mut regs,
951            0x040,
952            UARTIS::OE::SET.value | UARTIS::PE::SET.value,
953        );
954        write_test_reg(&mut regs, 0x018, UARTFR::RXFE::SET.value);
955
956        let snapshot = uart.take_irq_snapshot();
957        assert!(snapshot.claimed);
958        assert!(snapshot.sources.contains(IrqSource::RX_STATUS));
959
960        let sample = uart.read_rx().expect("saved RX status should be available");
961        assert_eq!(sample.byte, None);
962        assert_eq!(sample.flag, RxFlag::Parity);
963        assert!(sample.overrun);
964        assert!(uart.read_rx().is_none());
965    }
966
967    #[test]
968    fn serial_core_tx_irq_drains_software_fifo() {
969        let (mut regs, uart) = pl011_with_registers();
970        let parts = started_parts(uart);
971        let mut tx = parts.tx;
972        let mut irq = parts.irq;
973
974        write_test_reg(&mut regs, 0x018, UARTFR::TXFF::SET.value);
975        assert_eq!(tx.submit(b"x").accepted, 1);
976        assert_eq!(tx.chars_in_buffer(), 1);
977
978        write_test_reg(&mut regs, 0x018, 0);
979        write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
980        let outcome = irq.handle(owner_lease());
981        assert!(outcome.claimed);
982        assert_eq!(outcome.tx_sent, 1);
983        assert_eq!(regs.uartdr.get() as u8, b'x');
984        assert_eq!(tx.chars_in_buffer(), 0);
985    }
986
987    #[test]
988    fn tx_irq_snapshot_acknowledges_tx_interrupt() {
989        let (mut regs, mut uart) = pl011_with_registers();
990
991        write_test_reg(&mut regs, 0x040, UARTIS::TX::SET.value);
992        let snapshot = uart.take_irq_snapshot();
993
994        assert!(snapshot.claimed);
995        assert!(snapshot.sources.contains(IrqSource::TX_SPACE));
996        assert_eq!(
997            read_test_reg(&regs, 0x044) & UARTIS::TX::SET.value,
998            UARTIS::TX::SET.value
999        );
1000    }
1001
1002    #[test]
1003    fn set_config_preserves_enabled_tx_and_rx_paths() {
1004        let (regs, mut uart) = pl011_with_registers();
1005        regs.uartcr
1006            .write(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
1007
1008        uart.set_config(&Config::new()).unwrap();
1009
1010        let cr = regs.uartcr.extract();
1011        assert!(cr.is_set(UARTCR::UARTEN));
1012        assert!(cr.is_set(UARTCR::TXE));
1013        assert!(cr.is_set(UARTCR::RXE));
1014    }
1015
1016    #[test]
1017    fn rx_available_mask_enables_timeout_and_error_interrupts() {
1018        let (regs, mut uart) = pl011_with_registers();
1019
1020        uart.set_irq_mask(InterruptMask::RX_AVAILABLE);
1021
1022        let imsc = regs.uartimsc.extract();
1023        assert!(imsc.is_set(UARTIS::RX));
1024        assert!(imsc.is_set(UARTIS::RT));
1025        assert!(imsc.is_set(UARTIS::FE));
1026        assert!(imsc.is_set(UARTIS::PE));
1027        assert!(imsc.is_set(UARTIS::BE));
1028        assert!(imsc.is_set(UARTIS::OE));
1029        assert_eq!(uart.get_irq_mask(), InterruptMask::RX_AVAILABLE);
1030    }
1031
1032    #[test]
1033    fn hard_irq_does_not_claim_rx_ready_without_mis() {
1034        let (mut regs, mut uart) = pl011_with_registers();
1035
1036        uart.set_irq_mask(InterruptMask::RX_AVAILABLE);
1037        write_test_reg(&mut regs, 0x040, 0);
1038        write_test_reg(&mut regs, 0x018, 0);
1039
1040        assert!(uart.handle_irq().is_empty());
1041    }
1042
1043    #[test]
1044    fn raw_rx_ready_is_visible_without_irq_snapshot() {
1045        let (mut regs, mut uart) = pl011_with_registers();
1046
1047        uart.set_irq_mask(InterruptMask::RX_AVAILABLE);
1048        write_test_reg(&mut regs, 0x040, 0);
1049        write_test_reg(&mut regs, 0x018, 0);
1050        regs.uartdr.set(UARTDR::DATA.val(b'r' as u32).into());
1051
1052        let status = uart.poll_status();
1053        assert!(status.rx_ready());
1054        let sample = uart.read_rx().expect("RX sample should be available");
1055        assert_eq!(sample.byte, Some(b'r'));
1056        assert_eq!(sample.flag, RxFlag::Normal);
1057    }
1058}