sel4_pl011_driver/
device.rs1use core::ops::Deref;
8
9use tock_registers::interfaces::{Readable, Writeable};
10use tock_registers::registers::{ReadOnly, ReadWrite, WriteOnly};
11use tock_registers::{register_bitfields, register_structs};
12
13register_structs! {
14 #[allow(non_snake_case)]
15 pub RegisterBlock {
16 (0x000 => DR: ReadWrite<u8>),
17 (0x001 => _reserved0),
18 (0x018 => FR: ReadOnly<u32, FR::Register>),
19 (0x01c => _reserved1),
20 (0x038 => IMSC: ReadWrite<u32, IMSC::Register>),
21 (0x03c => _reserved2),
22 (0x044 => ICR: WriteOnly<u32, ICR::Register>),
23 (0x048 => @END),
24 }
25}
26
27register_bitfields! {
28 u32,
29
30 FR [
31 TXFF OFFSET(5) NUMBITS(1) [],
32 RXFE OFFSET(4) NUMBITS(1) [],
33 ],
34
35 IMSC [
36 RXIM OFFSET(4) NUMBITS(1) [],
37 ],
38
39 ICR [
40 ALL OFFSET(0) NUMBITS(11) [],
41 ],
42}
43
44pub struct Device {
45 ptr: *mut RegisterBlock,
46}
47
48impl Device {
49 pub const unsafe fn new(ptr: *mut RegisterBlock) -> Self {
50 Self { ptr }
51 }
52
53 const fn ptr(&self) -> *mut RegisterBlock {
54 self.ptr
55 }
56
57 pub fn init(&self) {
58 self.IMSC.write(IMSC::RXIM::SET);
59 }
60
61 pub fn put_char(&self, c: u8) {
62 while self.FR.matches_all(FR::TXFF::SET) {
63 core::hint::spin_loop();
64 }
65 self.DR.set(c)
66 }
67
68 pub fn get_char(&self) -> Option<u8> {
69 if self.FR.matches_all(FR::RXFE::CLEAR) {
70 Some(self.DR.get())
71 } else {
72 None
73 }
74 }
75
76 pub fn clear_all_interrupts(&self) {
77 self.ICR.write(ICR::ALL::SET);
78 }
79}
80
81impl Deref for Device {
82 type Target = RegisterBlock;
83
84 fn deref(&self) -> &Self::Target {
85 unsafe { &*self.ptr() }
86 }
87}