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 let mut serial = Self::new(base, clock_freq);
177 serial.open();
178 SerialDyn::new_boxed(serial)
179 }
180
181 fn registers(&self) -> &Pl011Registers {
182 unsafe { &*self.base.0.as_ptr() }
183 }
184
185 fn detect_clock_frequency(base: usize) -> u32 {
187 let registers = unsafe { &*(base as *const Pl011Registers) };
189
190 use tock_registers::interfaces::Readable;
191 let ibrd = registers.uartibrd.read(UARTIBRD::BAUD_DIVINT);
192
193 if ibrd > 0 && ibrd <= 0xFFFF {
195 let estimated_clock = 16 * ibrd * 115200;
198
199 if (1_000_000..=100_000_000).contains(&estimated_clock) {
201 return estimated_clock;
202 }
203 }
204
205 24_000_000
207 }
208
209 fn set_baudrate_internal(&self, baudrate: u32) -> Result<(), ConfigError> {
211 let bauddiv = self.clock_freq / (16 * baudrate);
217 let remainder = self.clock_freq % (16 * baudrate);
218 let fbrd = (remainder * 64 + (16 * baudrate / 2)) / (16 * baudrate);
219
220 if bauddiv == 0 || bauddiv > 0xFFFF {
221 return Err(ConfigError::InvalidBaudrate);
222 }
223
224 self.registers()
225 .uartibrd
226 .write(UARTIBRD::BAUD_DIVINT.val(bauddiv));
227 self.registers()
228 .uartfbrd
229 .write(UARTFBRD::BAUD_DIVFRAC.val(fbrd));
230
231 Ok(())
232 }
233
234 fn set_data_bits_internal(&self, bits: DataBits) -> Result<(), ConfigError> {
235 let wlen = match bits {
236 DataBits::Five => UARTLCR_H::WLEN::FiveBit,
237 DataBits::Six => UARTLCR_H::WLEN::SixBit,
238 DataBits::Seven => UARTLCR_H::WLEN::SevenBit,
239 DataBits::Eight => UARTLCR_H::WLEN::EightBit,
240 };
241
242 self.registers().uartlcr_h.modify(wlen);
243 Ok(())
244 }
245
246 fn set_stop_bits_internal(&self, bits: StopBits) -> Result<(), ConfigError> {
247 match bits {
248 StopBits::One => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::CLEAR),
249 StopBits::Two => self.registers().uartlcr_h.modify(UARTLCR_H::STP2::SET),
250 }
251
252 Ok(())
253 }
254
255 fn set_parity_internal(&self, parity: Parity) -> Result<(), ConfigError> {
256 match parity {
257 Parity::None => {
258 self.registers().uartlcr_h.modify(UARTLCR_H::PEN::CLEAR);
260 }
261 Parity::Odd => {
262 self.registers()
264 .uartlcr_h
265 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::CLEAR);
266 }
267 Parity::Even => {
268 self.registers()
270 .uartlcr_h
271 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::CLEAR);
272 }
273 Parity::Mark => {
274 self.registers()
276 .uartlcr_h
277 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::CLEAR + UARTLCR_H::SPS::SET);
278 }
279 Parity::Space => {
280 self.registers()
282 .uartlcr_h
283 .modify(UARTLCR_H::PEN::SET + UARTLCR_H::EPS::SET + UARTLCR_H::SPS::SET);
284 }
285 }
286
287 Ok(())
288 }
289
290 fn init(&self) {
292 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
294
295 while self.registers().uartfr.is_set(UARTFR::BUSY) {
297 core::hint::spin_loop();
298 }
299
300 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
302
303 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
305
306 #[cfg(debug_assertions)]
308 {
309 let ifls = self.registers().uartifls.get();
310 let lcr_h = self.registers().uartlcr_h.get();
311 log::debug!("UART IFLS: 0x{:02x}, LCR_H: 0x{:02x}", ifls, lcr_h);
312 log::debug!(" FIFO enabled: {}", lcr_h & (1 << 4) != 0);
313 log::debug!(" RX trigger level: 1/8");
314 log::debug!(" TX trigger level: 1/2");
315 }
316 self.registers().uartimsc.set(0); self.registers()
319 .uartcr
320 .modify(UARTCR::UARTEN::SET + UARTCR::TXE::SET + UARTCR::RXE::SET);
321 }
322
323 pub fn task_tx(&mut self) -> Option<crate::Sender> {
324 self.tx.take().map(crate::Sender::Pl011Sender)
325 }
326
327 pub fn task_rx(&mut self) -> Option<crate::Reciever> {
328 self.rx.take().map(crate::Reciever::Pl011Reciever)
329 }
330}
331
332#[derive(Clone, Copy, PartialEq, Eq)]
333struct Reg(NonNull<Pl011Registers>);
334
335unsafe impl Send for Reg {}
336
337impl Reg {
338 fn registers(&self) -> &Pl011Registers {
339 unsafe { self.0.as_ref() }
340 }
341}
342
343pub struct Pl011Sender {
344 base: Reg,
345}
346
347impl TSender for Pl011Sender {
348 fn write_byte(&mut self, byte: u8) -> bool {
349 RawSender::write_byte(self, byte)
350 }
351}
352
353impl RawSender for Pl011Sender {
354 fn write_byte(&mut self, byte: u8) -> bool {
355 if self.base.registers().uartfr.is_set(UARTFR::TXFF) {
356 return false;
357 }
358
359 self.base.registers().uartdr.set(byte as _);
360
361 true
362 }
363}
364
365pub struct Pl011Reciever {
366 base: Reg,
367}
368
369impl RawReciever for Pl011Reciever {
370 fn read_byte(&mut self) -> Option<Result<u8, TransferError>> {
371 if self.base.registers().uartfr.is_set(UARTFR::RXFE) {
372 return None;
373 }
374
375 let dr = self.base.registers().uartdr.extract();
376 let data = dr.read(UARTDR::DATA) as u8;
377
378 if dr.is_set(UARTDR::FE) {
379 return Some(Err(TransferError::Framing));
380 }
381
382 if dr.is_set(UARTDR::PE) {
383 return Some(Err(TransferError::Parity));
384 }
385
386 if dr.is_set(UARTDR::OE) {
387 return Some(Err(TransferError::Overrun(data)));
388 }
389
390 if dr.is_set(UARTDR::BE) {
391 return Some(Err(TransferError::Break));
392 }
393
394 Some(Ok(data))
395 }
396
397 fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<usize, TransBytesError> {
398 let mut count = 0;
399 let mut overrun_data = None;
400 for byte in bytes.iter_mut() {
401 match self.read_byte() {
402 Some(Ok(b)) => {
403 *byte = b;
404 }
405 Some(Err(TransferError::Overrun(b))) => {
406 overrun_data = Some(b);
407 *byte = b;
408 }
409 Some(Err(e)) => {
410 return Err(TransBytesError {
411 bytes_transferred: count,
412 kind: e,
413 });
414 }
415 None => {
416 if let Some(data) = overrun_data {
417 count = count.saturating_sub(1);
418
419 return Err(TransBytesError {
420 bytes_transferred: count,
421 kind: TransferError::Overrun(data),
422 });
423 }
424 break;
425 }
426 }
427 count += 1;
428 }
429 Ok(count)
430 }
431}
432
433pub struct Pl011IrqHandler {
434 base: Reg,
435}
436
437unsafe impl Sync for Pl011IrqHandler {}
438
439impl TIrqHandler for Pl011IrqHandler {
440 fn clean_interrupt_status(&self) -> InterruptMask {
441 let mis = self.base.registers().uartmis.extract();
442 let mut mask = InterruptMask::empty();
443
444 if mis.is_set(UARTIS::RX) {
445 mask |= InterruptMask::RX_AVAILABLE;
446 }
447 if mis.is_set(UARTIS::TX) {
448 mask |= InterruptMask::TX_EMPTY;
449 }
450
451 self.base.registers().uarticr.set(mis.get());
452
453 mask
454 }
455}
456
457impl InterfaceRaw for Pl011 {
458 type IrqHandler = Pl011IrqHandler;
459
460 type Sender = crate::Sender;
461
462 type Reciever = crate::Reciever;
463
464 fn name(&self) -> &str {
465 "PL011 UART"
466 }
467
468 fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
469 use tock_registers::interfaces::Readable;
470
471 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) {
478 core::hint::spin_loop();
479 }
480
481 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
483
484 if let Some(baudrate) = config.baudrate {
486 self.set_baudrate_internal(baudrate)?;
487 }
488 if let Some(data_bits) = config.data_bits {
489 self.set_data_bits_internal(data_bits)?;
490 }
491 if let Some(stop_bits) = config.stop_bits {
492 self.set_stop_bits_internal(stop_bits)?;
493 }
494 if let Some(parity) = config.parity {
495 self.set_parity_internal(parity)?;
496 }
497
498 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
500
501 if original_enable {
503 self.registers().uartcr.modify(UARTCR::UARTEN::SET); }
505
506 Ok(())
507 }
508
509 fn baudrate(&self) -> u32 {
510 let ibrd = self.registers().uartibrd.read(UARTIBRD::BAUD_DIVINT);
511 let fbrd = self.registers().uartfbrd.read(UARTFBRD::BAUD_DIVFRAC);
512
513 let divisor = ibrd * 64 + fbrd;
516 if divisor == 0 {
517 return 0;
518 }
519
520 self.clock_freq * 64 / (16 * divisor)
521 }
522
523 fn data_bits(&self) -> DataBits {
524 let wlen = self.registers().uartlcr_h.read(UARTLCR_H::WLEN);
525
526 match wlen {
527 0 => DataBits::Five,
528 1 => DataBits::Six,
529 2 => DataBits::Seven,
530 3 => DataBits::Eight,
531 _ => DataBits::Eight, }
533 }
534
535 fn stop_bits(&self) -> StopBits {
536 if self.registers().uartlcr_h.is_set(UARTLCR_H::STP2) {
537 StopBits::Two
538 } else {
539 StopBits::One
540 }
541 }
542
543 fn parity(&self) -> Parity {
544 if !self.registers().uartlcr_h.is_set(UARTLCR_H::PEN) {
545 Parity::None
546 } else if self.registers().uartlcr_h.is_set(UARTLCR_H::SPS) {
547 if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
549 Parity::Space
550 } else {
551 Parity::Mark
552 }
553 } else {
554 if self.registers().uartlcr_h.is_set(UARTLCR_H::EPS) {
556 Parity::Even
557 } else {
558 Parity::Odd
559 }
560 }
561 }
562
563 fn open(&mut self) {
564 self.init()
565 }
566
567 fn close(&mut self) {
568 self.registers().uartcr.modify(UARTCR::UARTEN::CLEAR);
570 }
571
572 fn clock_freq(&self) -> Option<NonZeroU32> {
573 self.clock_freq.try_into().ok()
574 }
575
576 fn enable_loopback(&mut self) {
577 self.registers().uartcr.modify(UARTCR::LBE::SET);
578 }
579
580 fn disable_loopback(&mut self) {
581 self.registers().uartcr.modify(UARTCR::LBE::CLEAR);
582 }
583
584 fn is_loopback_enabled(&self) -> bool {
585 self.registers().uartcr.is_set(UARTCR::LBE)
586 }
587
588 fn set_irq_mask(&mut self, mask: InterruptMask) {
589 let mut imsc = 0;
590 if mask.contains(InterruptMask::RX_AVAILABLE) {
591 imsc += UARTIS::RX::SET.value;
592 }
593 if mask.contains(InterruptMask::TX_EMPTY) {
594 imsc += UARTIS::TX::SET.value;
595 }
596
597 self.registers().uartimsc.set(imsc);
598 }
599
600 fn get_irq_mask(&self) -> InterruptMask {
601 let imsc = self.registers().uartimsc.extract();
602 let mut mask = InterruptMask::empty();
603
604 if imsc.is_set(UARTIS::RX) {
605 mask |= InterruptMask::RX_AVAILABLE;
606 }
607 if imsc.is_set(UARTIS::TX) {
608 mask |= InterruptMask::TX_EMPTY;
609 }
610
611 mask
612 }
613
614 fn base_addr(&self) -> usize {
615 self.base.0.as_ptr() as usize
616 }
617
618 fn irq_handler(&mut self) -> Option<Self::IrqHandler> {
619 self.irq.take()
620 }
621
622 fn take_tx(&mut self) -> Option<Self::Sender> {
623 self.task_tx()
624 }
625
626 fn take_rx(&mut self) -> Option<Self::Reciever> {
627 self.task_rx()
628 }
629
630 fn set_tx(&mut self, tx: Self::Sender) -> Result<(), SetBackError> {
631 let tx = match tx {
632 crate::Sender::Pl011Sender(s) => s,
633 _ => {
634 return Err(SetBackError::new(
635 self.base.0.as_ptr() as _,
636 0, ));
638 }
639 };
640
641 if self.base != tx.base {
642 return Err(SetBackError::new(
643 self.base.0.as_ptr() as _,
644 tx.base.0.as_ptr() as _,
645 ));
646 }
647
648 self.tx = Some(tx);
649 Ok(())
650 }
651
652 fn set_rx(&mut self, rx: Self::Reciever) -> Result<(), SetBackError> {
653 let rx = match rx {
654 crate::Reciever::Pl011Reciever(r) => r,
655 _ => {
656 return Err(SetBackError::new(
657 self.base.0.as_ptr() as _,
658 0, ));
660 }
661 };
662 if self.base != rx.base {
663 return Err(SetBackError::new(
664 self.base.0.as_ptr() as _,
665 rx.base.0.as_ptr() as _,
666 ));
667 }
668 self.rx = Some(rx);
669 Ok(())
670 }
671}
672
673impl Pl011 {
675 pub fn enable_fifo(&self, enable: bool) {
677 if enable {
678 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::SET);
679 } else {
680 self.registers().uartlcr_h.modify(UARTLCR_H::FEN::CLEAR);
681 }
682 }
683
684 pub fn set_fifo_trigger_level(&self, rx_level: u8, tx_level: u8) {
686 let rx_iflsel = match rx_level {
694 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
700
701 let tx_iflsel = match tx_level {
702 0..=2 => 0b000, 3..=4 => 0b001, 5..=8 => 0b010, 9..=12 => 0b011, _ => 0b100, };
708
709 self.registers()
710 .uartifls
711 .write(UARTIFLS::RXIFLSEL.val(rx_iflsel) + UARTIFLS::TXIFLSEL.val(tx_iflsel));
712 }
713}
714
715