sel4_pl011_driver/
device.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: BSD-2-Clause
5//
6
7use 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}