sel4_sp804_driver/
device.rs
1use core::ops::Deref;
10
11use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
12use tock_registers::registers::{ReadOnly, ReadWrite, WriteOnly};
13use tock_registers::{register_bitfields, register_structs};
14
15register_structs! {
16 #[allow(non_snake_case)]
17 pub TimerRegisterBlock {
18 (0x00 => Load: ReadWrite<u32>),
19 (0x04 => Value: ReadWrite<u32>),
20 (0x08 => Control: ReadWrite<u32, Control::Register>),
21 (0x0c => IntClr: WriteOnly<u32>),
22 (0x10 => RIS: ReadOnly<u32, RIS::Register>),
23 (0x14 => MIS: ReadOnly<u32, MIS::Register>),
24 (0x18 => BGLoad: ReadWrite<u32>),
25 (0x1c => _reserved0),
26 (0x20 => @END),
27 }
28}
29
30register_bitfields! {
31 u32,
32
33 pub Control [
34 TimerEn OFFSET(7) NUMBITS(1) [
35 Disabled = 0,
36 Enabled = 1,
37 ],
38 TimerMode OFFSET(6) NUMBITS(1) [
39 FreeRunning = 0,
40 Periodic = 1,
41 ],
42 IntEnable OFFSET(5) NUMBITS(1) [
43 Disabled = 0,
44 Enabled = 1,
45 ],
46 TimerPre OFFSET(2) NUMBITS(2) [
47 Div1 = 0b00,
48 Div16 = 0b01,
49 Div256 = 0b10
50 ],
51 TimerSize OFFSET(1) NUMBITS(1) [
52 Use16Bit = 0,
53 Use32Bit = 1,
54 ],
55 OneShot OFFSET(0) NUMBITS(1) [
56 Wrapping = 0,
57 OneShot = 1,
58 ]
59 ],
60
61 RIS [
62 RIS OFFSET(0) NUMBITS(1) [],
63 ],
64
65 MIS [
66 MIS OFFSET(0) NUMBITS(1) [],
67 ],
68}
69
70pub struct Device {
71 timer_1: Timer,
72 timer_2: Timer,
73}
74
75impl Device {
76 pub const unsafe fn new(ptr: *const ()) -> Self {
77 let ptr = ptr.cast::<TimerRegisterBlock>();
78 Device {
79 timer_1: Timer::new(ptr.offset(0)),
80 timer_2: Timer::new(ptr.offset(1)),
81 }
82 }
83
84 pub fn timer_1(&self) -> &Timer {
85 &self.timer_1
86 }
87
88 pub fn timer_2(&self) -> &Timer {
89 &self.timer_2
90 }
91}
92
93pub struct Timer {
94 ptr: *const TimerRegisterBlock,
95}
96
97#[allow(dead_code)]
98impl Timer {
99 pub const unsafe fn new(ptr: *const TimerRegisterBlock) -> Self {
100 Self { ptr }
101 }
102
103 fn ptr(&self) -> *const TimerRegisterBlock {
104 self.ptr
105 }
106
107 pub fn get_load(&self) -> u32 {
108 self.Load.get()
109 }
110
111 pub fn set_load(&self, value: u32) {
112 self.Load.set(value)
113 }
114
115 pub fn current_value(&self) -> u32 {
116 self.Value.get()
117 }
118
119 pub fn control(&self) -> &ReadWrite<u32, Control::Register> {
120 &self.Control
121 }
122
123 pub fn set_free_running_mode(&self) {
124 self.Control
125 .modify(Control::TimerMode::FreeRunning + Control::OneShot::Wrapping)
126 }
127
128 pub fn set_periodic_mode(&self) {
129 self.Control
130 .modify(Control::TimerMode::Periodic + Control::OneShot::Wrapping)
131 }
132
133 pub fn set_one_shot_mode(&self) {
134 self.Control.modify(Control::OneShot::OneShot)
135 }
136
137 pub fn set_backgroun_load(&self, value: u32) {
138 self.BGLoad.set(value)
139 }
140
141 pub fn clear_interrupt(&self) {
142 let value = 1; self.IntClr.set(value);
144 }
145
146 pub fn raw_interrupt_status(&self) -> bool {
147 self.RIS.read(RIS::RIS) != 0
148 }
149
150 pub fn masked_interrupt_status(&self) -> bool {
151 self.MIS.read(MIS::MIS) != 0
152 }
153}
154
155impl Deref for Timer {
156 type Target = TimerRegisterBlock;
157
158 fn deref(&self) -> &Self::Target {
159 unsafe { &*self.ptr() }
160 }
161}