1use core::{num::NonZeroU32, ptr::NonNull};
2
3use rdif_serial::{
4 BSerial, InterfaceRaw, SerialDyn, SetBackError, TIrqHandler, TSender, TransBytesError,
5 TransferError,
6};
7use tock_registers::{interfaces::*, register_bitfields, register_structs, registers::*};
8
9use crate::{
10 Config, ConfigError, DataBits, InterruptMask, Parity, RawReciever, RawSender, StopBits,
11};
12
13register_bitfields! [
14 u32,
15
16 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 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 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 UARTIBRD [
48 BAUD_DIVINT OFFSET(0) NUMBITS(16) []
49 ],
50
51 UARTFBRD [
53 BAUD_DIVFRAC OFFSET(0) NUMBITS(6) []
54 ],
55
56 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 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 UARTIFLS [
90 TXIFLSEL OFFSET(0) NUMBITS(3) [],
91 RXIFLSEL OFFSET(3) NUMBITS(3) []
92 ],
93
94 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 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>), (0x004 => uartrsr_ecr: ReadWrite<u32, UARTRSR_ECR::Register>), (0x008 => _reserved1), (0x018 => uartfr: ReadOnly<u32, UARTFR::Register>), (0x01c => _reserved2), (0x020 => uartilpr: ReadWrite<u32>), (0x024 => uartibrd: ReadWrite<u32, UARTIBRD::Register>), (0x028 => uartfbrd: ReadWrite<u32, UARTFBRD::Register>), (0x02c => uartlcr_h: ReadWrite<u32, UARTLCR_H::Register>), (0x030 => uartcr: ReadWrite<u32, UARTCR::Register>), (0x034 => uartifls: ReadWrite<u32, UARTIFLS::Register>), (0x038 => uartimsc: ReadWrite<u32, UARTIS::Register>), (0x03c => uartris: ReadOnly<u32, UARTIS::Register>), (0x040 => uartmis: ReadOnly<u32, UARTIS::Register>), (0x044 => uarticr: WriteOnly<u32, UARTIS::Register>), (0x048 => uartdmacr: ReadWrite<u32, UARTDMACR::Register>), (0x04c => _reserved3), (0x1000 => @END),
137 }
138}
139
140unsafe impl Sync for Pl011Registers {}
142
143pub struct Pl011 {
145 base: Reg,
146 clock_freq: u32,
147 tx: Option<Pl011Sender>,
148 rx: Option<Pl011Reciever>,
149 irq: Option<Pl011IrqHandler>,
150}
151
152impl Pl011 {
153 pub fn new_no_clock(base: NonNull<u8>) -> Self {
158 let clock_freq = Self::detect_clock_frequency(base.as_ptr() as usize);
160 Self::new(base, clock_freq)
161 }
162
163 pub fn new(base: NonNull<u8>, clock_freq: u32) -> Self {
164 let base = Reg(base.cast());
165
166 Self {
167 base,
168 clock_freq,
169 tx: Some(Pl011Sender { base }),
170 rx: Some(Pl011Reciever { base }),
171 irq: Some(Pl011IrqHandler { base }),
172 }
173 }
174
175 pub fn new_boxed(base: NonNull<u8>, clock_freq: u32) -> BSerial {
176 SerialDyn::new_boxed(Self::new(base, clock_freq))
177 }
178
179 fn registers(&self) -> &Pl011Registers {
180 unsafe { &*self.base.0.as_ptr() }
181 }
182
183 fn detect_clock_frequency(base: usize) -> u32 {
185 let registers = unsafe { &*(base as *const Pl011Registers) };
187
188 use tock_registers::interfaces::Readable;
189 let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
190
191 if ibrd > 0 && ibrd <= 0xFFFF {
193 let estimated_clock = 16 * ibrd * 115200;
196
197 if (1_000_000..=100_000_000).contains(&estimated_clock) {
199 return estimated_clock;
200 }
201 }
202
203 24_000_000
205 }
206
207 fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
209 let bauddiv = self.clock_freq / (16 * baudrate);
215 let remainder = self.clock_freq % (16 * baudrate);
216 let fbrd = (remainder * 64 + (16 * baudrate / 2)) / (16 * baudrate);
217
218 if bauddiv == 0 || bauddiv > 0xFFFF {
219 return Err(ConfigError::InvalidBaudrate);
220 }
221
222 self.registers()
223 .uartibrd
224 .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
225 self.registers()
226 .uartfbrd
227 .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
228
229 Ok(())
230 }
231
232 fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
233 let wlen = match bits {
234 DataBits::Five => UARTLCR_H::WLEN::FiveBit,
235 DataBits::Six => UARTLCR_H::WLEN::SixBit,
236 DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
237 DataBits::Eight => UARTLCR_H::WLEN::EightBit,
238 };
239
240 self.registers().uartlcr_h.modify(wlen);
241 Ok(())
242 }
243
244 fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
245 match bits {
246 StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
247 StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
248 }
249
250 Ok(())
251 }
252
253 fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
254 match parity {
255 Parity::None => {
256 self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
258 }
259 Parity::Odd => {
260 self.registers()
262 .uartlcr_h
263 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
264 }
265 Parity::Even => {
266 self.registers()
268 .uartlcr_h
269 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
270 }
271 Parity::Mark => {
272 self.registers()
274 .uartlcr_h
275 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
276 }
277 Parity::Space => {
278 self.registers()
280 .uartlcr_h
281 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
282 }
283 }
284
285 Ok(())
286 }
287
288 fn init(&self) {
290 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
292
293 while self.registers().uartfr.is_set(UARTFR::BUSY) {
295 core::hint::spin_loop();
296 }
297
298 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
300
301 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
303
304 #[cfg(debug_assertions)]
306 {
307 let ifls = self.registers().uartifls.get();
308 let lcr_h = self.registers().uartlcr_h.get();
309 log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
310 log::debug!(" FIFO enabled: {}", lcr_h & (1 << 4) != 0);
311 log::debug!(" RX trigger level: 1/8");
312 log::debug!(" TX trigger level: 1/2");
313 }
314 self.registers().uartimsc.set(0); self.registers()
317 .uartcr
318 .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
319 }
320
321 pub fn task_tx(&mut self) -> Option<crate::Sender> {
322 self.tx.take().map(crate::Sender::Pl011Sender)
323 }
324
325 pub fn task_rx(&mut self) -> Option<crate::Reciever> {
326 self.rx.take().map(crate::Reciever::Pl011Reciever)
327 }
328}
329
330#[derive(Clone, Copy, PartialEq, Eq)]
331struct Reg(NonNull<Pl011Registers>);
332
333unsafe impl Send for Reg {}
334
335impl Reg {
336 fn registers(&self) -> &Pl011Registers {
337 unsafe { self.0.as_ref() }
338 }
339}
340
341pub struct Pl011Sender {
342 base: Reg,
343}
344
345impl TSender for Pl011Sender {
346 fn write_byte(&mut self, byte: u8) -> bool {
347 RawSender::write_byte(self, byte)
348 }
349}
350
351impl RawSender for Pl011Sender {
352 fn write_byte(&mut self, byte: u8) -> bool {
353 if self.base.registers().uartfr.is_set(UARTFR::TXFF) {
354 return false;
355 }
356
357 self.base.registers().uartdr.set(byte as _);
358
359 true
360 }
361}
362
363pub struct Pl011Reciever {
364 base: Reg,
365}
366
367impl RawReciever for Pl011Reciever {
368 fn read_byte(&mut self) -> Option<Result<u8, TransferError>> {
369 if self.base.registers().uartfr.is_set(UARTFR::RXFE) {
370 return None;
371 }
372
373 let dr = self.base.registers().uartdr.extract();
374 let data = dr.read(UARTDR::DATA) as u8;
375
376 if dr.is_set(UARTDR::FE) {
377 return Some(Err(TransferError::Framing));
378 }
379
380 if dr.is_set(UARTDR::PE) {
381 return Some(Err(TransferError::Parity));
382 }
383
384 if dr.is_set(UARTDR::OE) {
385 return Some(Err(TransferError::Overrun(data)));
386 }
387
388 if dr.is_set(UARTDR::BE) {
389 return Some(Err(TransferError::Break));
390 }
391
392 Some(Ok(data))
393 }
394
395 fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
396 let mut count = 0;
397 let mut overrun_data = None;
398 for byte in bytes.iter_mut() {
399 match self.read_byte() {
400 Some(Ok(b)) => {
401 *byte = b;
402 }
403 Some(Err(TransferError::Overrun(b))) => {
404 overrun_data = Some(b);
405 *byte = b;
406 }
407 Some(Err(e)) => {
408 return Err(TransBytesError {
409 bytes_transferred: count,
410 kind: e,
411 });
412 }
413 None => {
414 if let Some(data) = overrun_data {
415 count = count.saturating_sub(1);
416
417 return Err(TransBytesError {
418 bytes_transferred: count,
419 kind: TransferError::Overrun(data),
420 });
421 }
422 break;
423 }
424 }
425 count += 1;
426 }
427 Ok(count)
428 }
429}
430
431pub struct Pl011IrqHandler {
432 base: Reg,
433}
434
435unsafe impl Sync for Pl011IrqHandler {}
436
437impl TIrqHandler for Pl011IrqHandler {
438 fn clean_interrupt_status(&self) -> InterruptMask {
439 let mis = self.base.registers().uartmis.extract();
440 let mut mask = InterruptMask::empty();
441
442 if mis.is_set(UARTIS::RX) {
443 mask |= InterruptMask::RX_AVAILABLE;
444 }
445 if mis.is_set(UARTIS::TX) {
446 mask |= InterruptMask::TX_EMPTY;
447 }
448
449 self.base.registers().uarticr.set(mis.get());
450
451 mask
452 }
453}
454
455impl InterfaceRaw for Pl011 {
456 type IrqHandler = Pl011IrqHandler;
457
458 type Sender = crate::Sender;
459
460 type Reciever = crate::Reciever;
461
462 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
463 use tock_registers::interfaces::Readable;
464
465 let original_enable = self.registers().uartcr.is_set(UARTCR::UARTEN); self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR); while self.registers().uartfr.is_set(UARTFR::BUSY) {
472 core::hint::spin_loop();
473 }
474
475 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
477
478 if let Some(baudrate) = config.baudrate {
480 self.set_baudrate_internal(baudrate)?;
481 }
482 if let Some(data_bits) = config.data_bits {
483 self.set_data_bits_internal(data_bits)?;
484 }
485 if let Some(stop_bits) = config.stop_bits {
486 self.set_stop_bits_internal(stop_bits)?;
487 }
488 if let Some(parity) = config.parity {
489 self.set_parity_internal(parity)?;
490 }
491
492 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
494
495 if original_enable {
497 self.registers().uartcr.modify(UARTCR::UARTEN::SET); }
499
500 Ok(())
501 }
502
503 fn baudrate(&self) -> u32 {
504 let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
505 let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
506
507 let divisor = ibrd * 64 + fbrd;
510 if divisor == 0 {
511 return 0;
512 }
513
514 self.clock_freq * 64 / (16 * divisor)
515 }
516
517 fn data_bits(&self) -> DataBits {
518 let wlen = self.registers().uartlcr_h.read(UARTLCR_H::WLEN);
519
520 match wlen {
521 0 => DataBits::Five,
522 1 => DataBits::Six,
523 2 => DataBits::Seven,
524 3 => DataBits::Eight,
525 _ => DataBits::Eight, }
527 }
528
529 fn stop_bits(&self) -> StopBits {
530 if self.registers().uartlcr_h.is_set(UARTLCR_H::STP2) {
531 StopBits::Two
532 } else {
533 StopBits::One
534 }
535 }
536
537 fn parity(&self) -> Parity {
538 if !self.registers().uartlcr_h.is_set(UARTLCR_H::PEN) {
539 Parity::None
540 } else if self.registers().uartlcr_h.is_set(UARTLCR_H::SPS) {
541 if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
543 Parity::Space
544 } else {
545 Parity::Mark
546 }
547 } else {
548 if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
550 Parity::Even
551 } else {
552 Parity::Odd
553 }
554 }
555 }
556
557 fn open(&mut self) {
558 self.init()
559 }
560
561 fn close(&mut self) {
562 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
564 }
565
566 fn clock_freq(&self) -> Option<NonZeroU32> {
567 self.clock_freq.try_into().ok()
568 }
569
570 fn enable_loopback(&mut self) {
571 self.registers().uartcr.modify(UARTCR::LBE::SET);
572 }
573
574 fn disable_loopback(&mut self) {
575 self.registers().uartcr.modify(UARTCR::LBE::CLEAR);
576 }
577
578 fn is_loopback_enabled(&self) -> bool {
579 self.registers().uartcr.is_set(UARTCR::LBE)
580 }
581
582 fn set_irq_mask(&mut self, mask: InterruptMask) {
583 let mut imsc = 0;
584 if mask.contains(InterruptMask::RX_AVAILABLE) {
585 imsc += UARTIS::RX::SET.value;
586 }
587 if mask.contains(InterruptMask::TX_EMPTY) {
588 imsc += UARTIS::TX::SET.value;
589 }
590
591 self.registers().uartimsc.set(imsc);
592 }
593
594 fn get_irq_mask(&self) -> InterruptMask {
595 let imsc = self.registers().uartimsc.extract();
596 let mut mask = InterruptMask::empty();
597
598 if imsc.is_set(UARTIS::RX) {
599 mask |= InterruptMask::RX_AVAILABLE;
600 }
601 if imsc.is_set(UARTIS::TX) {
602 mask |= InterruptMask::TX_EMPTY;
603 }
604
605 mask
606 }
607
608 fn base_addr(&self) -> usize {
609 self.base.0.as_ptr() as usize
610 }
611
612 fn irq_handler(&mut self) -> Option<Self::IrqHandler> {
613 self.irq.take()
614 }
615
616 fn take_tx(&mut self) -> Option<Self::Sender> {
617 self.task_tx()
618 }
619
620 fn take_rx(&mut self) -> Option<Self::Reciever> {
621 self.task_rx()
622 }
623
624 fn set_tx(&mut self, tx: Self::Sender) -> Result<(), SetBackError> {
625 let tx = match tx {
626 crate::Sender::Pl011Sender(s) => s,
627 _ => {
628 return Err(SetBackError::new(
629 self.base.0.as_ptr() as _,
630 0, ));
632 }
633 };
634
635 if self.base != tx.base {
636 return Err(SetBackError::new(
637 self.base.0.as_ptr() as _,
638 tx.base.0.as_ptr() as _,
639 ));
640 }
641
642 self.tx = Some(tx);
643 Ok(())
644 }
645
646 fn set_rx(&mut self, rx: Self::Reciever) -> Result<(), SetBackError> {
647 let rx = match rx {
648 crate::Reciever::Pl011Reciever(r) => r,
649 _ => {
650 return Err(SetBackError::new(
651 self.base.0.as_ptr() as _,
652 0, ));
654 }
655 };
656 if self.base != rx.base {
657 return Err(SetBackError::new(
658 self.base.0.as_ptr() as _,
659 rx.base.0.as_ptr() as _,
660 ));
661 }
662 self.rx = Some(rx);
663 Ok(())
664 }
665}
666
667impl Pl011 {
669 pub fn enable_fifo(&self, enable: bool) {
671 if enable {
672 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
673 } else {
674 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
675 }
676 }
677
678 pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
680 let rx_iflsel = match rx_level {
688 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
694
695 let tx_iflsel = match tx_level {
696 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
702
703 self.registers()
704 .uartifls
705 .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
706 }
707}
708
709