arm_pl011_rs/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3
4use core::{
5    future::Future,
6    ptr::NonNull,
7    sync::atomic::{fence, Ordering},
8};
9
10use bitflags::bitflags;
11use embedded_io::ErrorType;
12use spin_on::spin_on;
13use tock_registers::{
14    fields::FieldValue, interfaces::*, register_bitfields, register_structs, registers::*,
15};
16
17#[derive(Debug)]
18pub enum ErrorKind {
19    Framing,
20    Parity,
21    Break,
22    Overrun,
23}
24
25register_bitfields! [
26    // First parameter is the register width. Can be u8, u16, u32, or u64.
27    u32,
28
29    Data [
30        DATA  OFFSET(0) NUMBITS(8) [],
31        FRAMING_ERROR    OFFSET(8) NUMBITS(1) [],
32        PARITY_ERROR OFFSET(9) NUMBITS(1) [],
33        BREAK_ERROR OFFSET(10) NUMBITS(1) [],
34        OVERRUN_ERROR OFFSET(11) NUMBITS(1) [],
35    ],
36
37    Fr [
38        CLEAR_TO_SEND OFFSET(0) NUMBITS(1) [],
39        DATA_SET_READY OFFSET(1) NUMBITS(1) [],
40        DATA_CARRIER_DETECT OFFSET(2) NUMBITS(1) [],
41        BUSY OFFSET(3) NUMBITS(1) [],
42        RX_FIFO_EMPTY OFFSET(4) NUMBITS(1) [],
43        TX_FIFO_FULL OFFSET(5) NUMBITS(1) [],
44        RX_FIFO_FULL OFFSET(6) NUMBITS(1) [],
45        TX_FIFO_EMPTY OFFSET(7) NUMBITS(1) [],
46    ],
47
48    LineControlRegister [
49        SEND_BREAK OFFSET(0) NUMBITS(1) [],
50        PARITY_ENABLE OFFSET(1) NUMBITS(1) [],
51        EVEN_PARITY_SELECT OFFSET(2) NUMBITS(1) [
52            Odd = 0,
53            Even = 1,
54        ],
55        TWO_STOP_BITS_SELECT OFFSET(3) NUMBITS(1) [],
56        ENABLE_FIFO OFFSET(4) NUMBITS(1) [],
57        WORD_LEN OFFSET(5) NUMBITS(2) [
58            B5 = 0b00,
59            B6 = 0b01,
60            B7 = 0b10,
61            B8 = 0b11,
62        ],
63        STICK_PARITY_SELECT OFFSET(7) NUMBITS(1)[],
64    ],
65
66    ControlRegister [
67        ENABLE OFFSET(0) NUMBITS(1) [],
68        SIR_ENABLE OFFSET(1) NUMBITS(1) [],
69        SIR_LP OFFSET(2) NUMBITS(1) [],
70        LOOPBACK_ENABLE OFFSET(7) NUMBITS(1) [],
71        TX_ENABLE OFFSET(8) NUMBITS(1) [],
72        RX_ENABLE OFFSET(9) NUMBITS(1) [],
73        DATA_TRANSMIT_READY OFFSET(10) NUMBITS(1) [],
74        REQUEST_TO_SEND OFFSET(11) NUMBITS(1) [],
75        OUT1 OFFSET(12) NUMBITS(1) [],
76        OUT2 OFFSET(13) NUMBITS(1) [],
77        RTS_ENABLE OFFSET(14) NUMBITS(1) [],
78        CTS_ENABLE OFFSET(15) NUMBITS(1) [],
79    ],
80    IFLS [
81        TXIFLSEL OFFSET(0) NUMBITS(2) [],
82        RXIFLSEL OFFSET(3) NUMBITS(2) [],
83    ],
84];
85
86register_structs! {
87    Registers {
88        (0x00 => dr: ReadWrite<u32, Data::Register>),
89        (0x04 => _reserved0),
90        /// Flag Register.
91        (0x18 => fr: ReadOnly<u32, Fr::Register>),
92        (0x1c => _reserved1),
93        (0x24 => ibrd: ReadWrite<u32>),
94        (0x28 => fbrd: ReadWrite<u32>),
95        (0x2c => lcr_h: ReadWrite<u32, LineControlRegister::Register>),
96        /// Control register.
97        (0x30 => cr: ReadWrite<u32, ControlRegister::Register>),
98        /// Interrupt FIFO Level Select Register.
99        (0x34 => ifls: ReadWrite<u32, IFLS::Register>),
100        /// Interrupt Mask Set Clear Register.
101        (0x38 => imsc: ReadWrite<u32>),
102        /// Raw Interrupt Status Register.
103        (0x3c => ris: ReadOnly<u32>),
104        /// Masked Interrupt Status Register.
105        (0x40 => mis: ReadOnly<u32>),
106        /// Interrupt Clear Register.
107        (0x44 => icr: WriteOnly<u32>),
108        (0x48 => @END),
109    }
110}
111
112/// Word length.
113#[derive(Clone, Copy, PartialEq, Eq, Debug)]
114pub enum DataBits {
115    Bits5,
116    Bits6,
117    Bits7,
118    Bits8,
119}
120
121impl From<DataBits> for FieldValue<u32, LineControlRegister::Register> {
122    fn from(val: DataBits) -> Self {
123        match val {
124            DataBits::Bits5 => LineControlRegister::WORD_LEN::B5,
125            DataBits::Bits6 => LineControlRegister::WORD_LEN::B6,
126            DataBits::Bits7 => LineControlRegister::WORD_LEN::B7,
127            DataBits::Bits8 => LineControlRegister::WORD_LEN::B8,
128        }
129    }
130}
131
132/// Parity bit.
133#[derive(Clone, Copy, PartialEq, Eq, Debug)]
134pub enum Parity {
135    None,
136    Even,
137    Odd,
138}
139
140/// Stop bits.
141#[derive(Clone, Copy, PartialEq, Eq, Debug)]
142pub enum StopBits {
143    #[doc = "1 stop bit"]
144    STOP1,
145    #[doc = "2 stop bits"]
146    STOP2,
147}
148
149pub struct Config {
150    pub baud_rate: u32,
151    pub clock_freq: u64,
152    pub data_bits: DataBits,
153    pub stop_bits: StopBits,
154    pub parity: Parity,
155}
156
157pub struct Pl011 {
158    base: usize,
159}
160
161impl Pl011 {
162    pub async fn new(base: NonNull<u8>, config: Option<Config>) -> Self {
163        let mut s = Self {
164            base: base.as_ptr() as usize,
165        };
166        s.set_config(config).await;
167        s
168    }
169
170    pub fn new_sync(base: NonNull<u8>, config: Option<Config>) -> Self {
171        spin_on(Self::new(base, config))
172    }
173
174    async fn flush_all(&mut self) {
175        self.wait_expect(|reg| reg.fr.matches_all(Fr::TX_FIFO_EMPTY::SET + Fr::BUSY::CLEAR))
176            .await;
177    }
178
179    pub async fn set_config(&mut self, config: Option<Config>) {
180        self.flush_all().await;
181
182        // 1. Disable the UART.
183        self.reg().cr.modify(ControlRegister::ENABLE::CLEAR);
184
185        // 2. Wait for the end of transmission or reception of the current character.
186
187        // 3. Flush the transmit FIFO by setting the FEN bit to 0 in the Line Control Register, UARTLCR_H.
188        self.reg()
189            .lcr_h
190            .modify(LineControlRegister::ENABLE_FIFO::CLEAR);
191
192        fence(Ordering::Release);
193
194        if let Some(config) = config {
195            let pen;
196            let eps;
197            let sps;
198
199            match config.parity {
200                Parity::None => {
201                    pen = LineControlRegister::PARITY_ENABLE::CLEAR;
202                    eps = LineControlRegister::EVEN_PARITY_SELECT::CLEAR;
203                    sps = LineControlRegister::STICK_PARITY_SELECT::CLEAR;
204                }
205                Parity::Even => {
206                    pen = LineControlRegister::PARITY_ENABLE::SET;
207                    eps = LineControlRegister::EVEN_PARITY_SELECT::SET;
208                    sps = LineControlRegister::STICK_PARITY_SELECT::CLEAR;
209                }
210                Parity::Odd => {
211                    pen = LineControlRegister::PARITY_ENABLE::SET;
212                    eps = LineControlRegister::EVEN_PARITY_SELECT::CLEAR;
213                    sps = LineControlRegister::STICK_PARITY_SELECT::CLEAR;
214                }
215            }
216            let word_len = config.data_bits.into();
217            let stp2 = match config.stop_bits {
218                StopBits::STOP1 => LineControlRegister::TWO_STOP_BITS_SELECT::CLEAR,
219                StopBits::STOP2 => LineControlRegister::TWO_STOP_BITS_SELECT::SET,
220            };
221
222            let baud_rate_div = (8 * config.clock_freq) / config.baud_rate as u64;
223            let mut baud_ibrd = baud_rate_div >> 7;
224            let mut baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2;
225
226            if baud_ibrd == 0 {
227                baud_ibrd = 1;
228                baud_fbrd = 0;
229            } else if baud_ibrd >= 65535 {
230                baud_ibrd = 65535;
231                baud_fbrd = 0;
232            }
233
234            self.reg().ibrd.set(baud_ibrd as u32);
235            self.reg().fbrd.set(baud_fbrd as u32);
236
237            self.reg()
238                .lcr_h
239                .write(LineControlRegister::ENABLE_FIFO::SET + word_len + pen + eps + sps + stp2);
240        } else {
241            self.reg()
242                .lcr_h
243                .modify(LineControlRegister::ENABLE_FIFO::SET);
244        }
245
246        self.reg().cr.write(
247            ControlRegister::ENABLE::SET
248                + ControlRegister::TX_ENABLE::SET
249                + ControlRegister::RX_ENABLE::SET,
250        );
251    }
252    pub fn set_config_sync(&mut self, config: Option<Config>) {
253        spin_on(self.set_config(config));
254    }
255
256    async fn read(&self) -> Result<u8, ErrorKind> {
257        self.wait_expect(|reg| reg.fr.read(Fr::RX_FIFO_EMPTY) == 0)
258            .await;
259
260        let val = self.reg().dr.get();
261        let b = Data::DATA.read(val) as u8;
262
263        if Data::FRAMING_ERROR.is_set(val) {
264            return Err(ErrorKind::Framing);
265        }
266        if Data::PARITY_ERROR.is_set(val) {
267            return Err(ErrorKind::Parity);
268        }
269        if Data::OVERRUN_ERROR.is_set(val) {
270            return Err(ErrorKind::Overrun);
271        }
272        if Data::BREAK_ERROR.is_set(val) {
273            return Err(ErrorKind::Break);
274        }
275
276        Ok(b)
277    }
278
279    async fn write(&self, data: u8) {
280        self.wait_expect(|reg| reg.fr.read(Fr::TX_FIFO_FULL) == 0)
281            .await;
282
283        self.reg().dr.write(Data::DATA.val(data as u32));
284    }
285
286    fn reg(&self) -> &Registers {
287        unsafe { &*(self.base as *const Registers) }
288    }
289
290    async fn wait_expect<F>(&self, expect: F)
291    where
292        F: Fn(&Registers) -> bool,
293    {
294        WaitExpectFuture {
295            base: self.base,
296            expect,
297        }
298        .await;
299    }
300
301    pub fn set_tx_fifo_threadhold(&mut self, threshold: Threshold) {
302        self.reg().ifls.modify(IFLS::TXIFLSEL.val(threshold as _));
303    }
304
305    pub fn set_rx_fifo_threadhold(&mut self, threshold: Threshold) {
306        self.reg().ifls.modify(IFLS::RXIFLSEL.val(threshold as _));
307    }
308
309    pub fn write_imsc(&mut self, mask: IMSC) {
310        self.reg().imsc.set(mask.bits());
311    }
312
313    pub fn read_ris(&self) -> RIS {
314        RIS::from_bits_truncate(self.reg().ris.get())
315    }
316    pub fn read_mis(&self) -> MIS {
317        MIS::from_bits_truncate(self.reg().mis.get())
318    }
319
320    pub fn write_icr(&mut self, mask: RIS) {
321        self.reg().icr.set(mask.bits());
322    }
323}
324
325bitflags! {
326    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
327    pub struct IMSC: u32 {
328        /// nUARTRI 调制解调中断屏蔽
329        const RIMIM = 1 << 0;
330        /// nUARTCTS 调制解调中断屏蔽
331        const CTSMIM = 1 << 1;
332        /// nUARTDCD 调制解调中断屏蔽
333        const CDCDMIM = 1 << 2;
334        const DSRMIM = 1 << 3;
335        /// 接收中断屏蔽
336        const RXIM = 1 << 4;
337        /// 发送中断屏蔽
338        const TXIM = 1 << 5;
339        /// 接收超时中断屏蔽
340        const RTIM = 1 << 6;
341        const FEIM = 1 << 7;
342        const PEIM = 1 << 8;
343        const BEIM = 1 << 9;
344        const OEIM = 1 << 10;
345    }
346
347    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
348    pub struct RIS: u32 {
349        const RIRMIS = 1 << 0;
350        const CTSRMIS = 1 << 1;
351        const DCDRMIS = 1 << 2;
352        const DSRRMIS = 1 << 3;
353        const RXRIS = 1 << 4;
354        const TXRIS = 1 << 5;
355        const RTRIS = 1 << 6;
356        const FERIS = 1 << 7;
357        const PERIS = 1 << 8;
358        const BERIS = 1 << 9;
359        const OERIS = 1 << 10;
360    }
361    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
362    pub struct MIS: u32 {
363        const RIMMIS = 1 << 0;
364        const CTSMMIS = 1 << 1;
365        const DCDMMIS = 1 << 2;
366        const DSRMMIS = 1 << 3;
367        const RXMIS = 1 << 4;
368        const TXMIS = 1 << 5;
369        const RTMIS = 1 << 6;
370        const FEMIS = 1 << 7;
371        const PEMIS = 1 << 8;
372        const BEMIS = 1 << 9;
373        const OEMIS = 1 << 10;
374    }
375
376    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
377    pub struct ICR: u32 {
378        const RIMIC = 1 << 0;
379        const CTSMIC = 1 << 1;
380        const DCDMIC = 1 << 2;
381        const DSRMIC = 1 << 3;
382        const RXIC = 1 << 4;
383        const TXIC = 1 << 5;
384        const RTIC = 1 << 6;
385        const FEIC = 1 << 7;
386        const PEIC = 1 << 8;
387        const BEIC = 1 << 9;
388        const OEIC = 1 << 10;
389    }
390}
391
392#[repr(C)]
393#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
394pub enum Threshold {
395    /// FIFO ≤ 1/8 full
396    Level1 = 000,
397    /// FIFO ≤ 1/4 full
398    Level2 = 0b001,
399    /// FIFO ≤ 1/2 full
400    Level3 = 0b010,
401    /// FIFO ≤ 3/4 full
402    Level4 = 0b011,
403    /// FIFO ≤ 7/8 full
404    Level5 = 0b100,
405}
406
407struct WaitExpectFuture<F>
408where
409    F: Fn(&Registers) -> bool,
410{
411    base: usize,
412    expect: F,
413}
414
415impl<F> Future for WaitExpectFuture<F>
416where
417    F: Fn(&Registers) -> bool,
418{
419    type Output = ();
420
421    fn poll(
422        self: core::pin::Pin<&mut Self>,
423        cx: &mut core::task::Context<'_>,
424    ) -> core::task::Poll<Self::Output> {
425        let reg = unsafe { &*(self.base as *const Registers) };
426        let expect = (self.expect)(reg);
427        if expect {
428            core::task::Poll::Ready(())
429        } else {
430            cx.waker().wake_by_ref();
431            core::task::Poll::Pending
432        }
433    }
434}
435
436impl embedded_io::Error for ErrorKind {
437    fn kind(&self) -> embedded_io::ErrorKind {
438        match self {
439            ErrorKind::Framing => embedded_io::ErrorKind::InvalidData,
440            ErrorKind::Parity => embedded_io::ErrorKind::InvalidData,
441            ErrorKind::Break => embedded_io::ErrorKind::InvalidData,
442            ErrorKind::Overrun => embedded_io::ErrorKind::Other,
443        }
444    }
445}
446
447impl ErrorType for Pl011 {
448    type Error = ErrorKind;
449}
450
451impl embedded_io::Write for Pl011 {
452    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
453        spin_on(Pl011::write(self, buf[0]));
454        Ok(1)
455    }
456
457    fn flush(&mut self) -> Result<(), Self::Error> {
458        Ok(())
459    }
460}
461impl embedded_io::Read for Pl011 {
462    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
463        let b = spin_on(Pl011::read(self))?;
464        buf[0] = b;
465        Ok(1)
466    }
467}
468
469impl embedded_io_async::Write for Pl011 {
470    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
471        Pl011::write(self, buf[0]).await;
472        Ok(1)
473    }
474}
475impl embedded_io_async::Read for Pl011 {
476    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
477        let b = Pl011::read(self).await?;
478        buf[0] = b;
479        Ok(1)
480    }
481}